Java反射

来源:互联网 发布:淘宝收件人名字大全 编辑:程序博客网 时间:2024/06/16 12:42
 1、Class类
Java运行时系统始终为对象维护一个被称为运行时的类型标示,追踪者每个对象所属的类,通过Class类保存信息。
Class cl = obj.getClass();
常用方法:
String getName()   如cl.getName();

String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称
static Class forName(String className)  如Class.forName("java.util.Date")

返回与带有给定字符串名的类或接口相关联的 Class 对象T newInstance()  如 Class.forName("java.util.Date").newInstance

 创建此 Class 对象所表示的类的一个新实例
虚拟机为每个类型管理唯一一个Class对象,可以利用==进行两个类对象的比较操作
if(obj1.getClass() == obj2.getClass())

Field[] getFields() 
返回记录了这个类或其超类的

 Class<?>[]getDeclaredClasses()
          返回 Class 对象的一个数组,这些对象反映声明为此 Class 对象所表示的类的成员的所有类和接口。 Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes)
          返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。 Constructor<?>[]getDeclaredConstructors()
          返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。 FieldgetDeclaredField(String name)
          返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 Field[]getDeclaredFields()
          返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。 MethodgetDeclaredMethod(String name, Class<?>... parameterTypes)
          返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 Method[]getDeclaredMethods()
          返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 Class<?>getDeclaringClass()
          如果此 Class 对象所表示的类或接口是另一个类的成员,则返回的 Class 对象表示该对象的声明类。


 MethodgetMethod(String name, Class<?>... parameterTypes)
          返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 Method[]getMethods()
          返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
2、利用反射分析类
java.lang.reflect 包中有三个类:Field Method Constructor分别用于描述类的域(属性)、方法和构造器。
三个类都有的方法:
 String getName() 返回对应的名称   
 int getModifiers() 用来标识访问权限public、static、private等,可以使用静态方法Modifier.toString(int)打印修饰符
Field特有方法
  Class getType() 返回描述属性所属类型的Class对象
Method特有方法
   Class getReturnType() 返回一个用于描述返回类型的Class对象
Method、Constructor共有有方法
    Class[] getParameterTypes() 返回参数类型

3、在运行时使用反射分析对象
Field类中的方法Object get(Object obj)

返回指定对象上此 Field 表示的字段的值。
例如:
    Employee harry = new Employee("sunkai", "3500, 10, 1, 1992);
    Class cl = harry.getClass();
    Field f = cl.getDeclaredField("name");       //name为Employee 类的一个属性
    Object v = f.get(harry);                                //此时v中保存返回的String sunkai
若属性为基础类型,get方法会将其自动打包为对象。
但是如果name属性为私有时,此段代码会抛出异常,可以采用setAccessible方法将其设置可以用反射访问。

 voidsetAccessible(boolean flag)
          将此对象的 accessible 标志设置为指示的布尔值。flag为true时,屏蔽Java语音的访问检查,使得对象私有属性也可以被查询和设置。
   

static voidsetAccessible(AccessibleObject[] array, boolean flag)
          使用单一安全性检查(为了提高效率)为一组对象设置 accessible 标志的便捷方法。
setAccessible方法是AccessibleObject类中的一个方法,他是Field、Method和Constructor类的公共超类,这个特性是为了调试、持久存储和相似机制提供的。如下例程实现toString()方法,使用setAccessible方法将所有域设置为可访问的。
public String toString(Object obj)
    {
        Class cl = obj.getClass();
        String r = cl.getName();

        do{
            r += "[";
            Field[] fields = cl.getDeclaredFields();
            AccessibleObject.setAccessible(fields, true);
            //get name and values of all fields
            for(Field f : fields)
            {
                if(!Modifier.isStatic(f.getModifiers()))
                {
                    if(!r.endsWith("[")){
                        r += ",";
                    }
                    r += f.getName() + " = ";
                    try{
                        Object value = f.get(obj);
                        r += value.toString();
                    }
                    catch(Exception e){
                        e.printStackTrace();
                    }
                }
            }
            r += "]";
            cl = cl.getSuperclass();
        }while(cl != null);
        return r;
    }

Array类中的静态方法newInstance能够构造新数组

static ObjectnewInstance(Class<?> componentType, int... dimensions)
          创建一个具有指定的组件类型和维度的新数组。

4、调用任意方法
Method类中有一个invoke方法,允许调用包装在当前对象中的方法

 Objectinvoke(Object obj, Object... args)
          对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。参数obj为隐式参数,若为静态方法则为null,args为显式参数
而Method对象则可以通过两种方法获得
1) 通过调用Class类中的getDeclareMethods方法,返回Method对象数组进行查找
2) 调用Class类的getMethod方法获得想要的方法。


 Method
getMethod(String name, Class<?>... parameterTypes)
          返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。Java中invoke的参数和返回值必须为Object,这就意味着必须进行多次的类型转换,且使用反射效率较低,所以Java要使用回调函数功能尽量使用接口进行回调。
0 0
原创粉丝点击