Java反射机制

来源:互联网 发布:淘宝做代理靠谱吗 编辑:程序博客网 时间:2024/06/09 02:49

1.1 反射机制的定义

在运行状态中,对于任意一个类,都可以获取类的方法和属性;对于任意一个对象,都可以调用对象的方法。这种动态地获取类信息或者动态地调用对象的方法的功能就叫做类的反射机制。

1.2 java.lang.Class

在Java程序运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,这项信息记录对象所属的类。虚拟机将会根据运行时类型信息选择正确的方法执行,用来保存这项信息的类便是Class类。
当ClassLoader找到需要调用的类时,就会加载它,并根据.class文件中记载的信息来产生一个独一无二的Class实例,该Class实例保存了该类的方法、字段等信息。以后JVM需要产生该类的实例时,就是根据内存中Classs实例的相关信息来进行。
1. Class是一个类,一个描述类的类,封装了描述方法的Method,描述字段的Field,描述构造器的Constructor等属性;
2. 通过反射可以得到某个类的数据成员名、方法、构造器以及它实现了哪些接口;
3. Class类的对象只能由系统来创建,一个类在JVM只有一个Class类实例;

1.2.1 Class对象的获取方式

Class对象可以通过以下方式获取:

//1. 通过Object类的getClass()方法Main0 t=new Main0();Class c=t.getClass();//2. 通过Class类的静态方法ofrName("完全限定名(即:包名+类名)")方法Class c2=Class.forName("com2.Main0");//3. 每一个类都有class属性Class c3=Main0.class;

1.2.2 Class类的常用方法

1. 创建对象

在获取Class类对象后,可以通过newInstance方法来创建Class对象对应类的对象,需要强调的是,newInstance调用的是类的默认构造函数,所以当使用newInstance方法时,必须保证Class对象对应的类中包含无参数构造函数;

Class c2=Class.forName("com2.Main0");Object o=c2.newInstance();   //调用Main0类的默认构造函数
2. 获取成员属性

获取成员属性的方法分为两大类:一类是获取所有的属性,另外一类是根据名字获取特定的属性。
2.1 获取所有属性方法有两个,如下所示:

//该方法将会返回包含所有public属性的Field数组//如果Class对象代表的类是一个类或者接口,它不包含public属性,那么返回数组的长度为0;//如果Class对象代表的是一个数组或者原始类型(如int),那么返回数组的长度为0;//如果Class对象代表一个类,那么将会返回当前类和继承而来的所有public属性;//如果Class对象代表一个接口,那么将会返回当前接口和所有扩展接口中的属性;public Field[] getFields();//该方法同样会返回一个Field对象的数组//该方法返回的Field对象数组为Class对象所代表的类中包括publicprotectedprivatedefault修饰的属性,但是不包含继承而来的属性;public Field[] getDeclaredFields();

上述两个方法的应用示例如下:

//getFields方法的示例public static void printFields(Class c){        Field[] fields=c.getFields();        StringBuffer sb=new StringBuffer();        sb.append(Modifier.toString(c.getModifiers())+"\t"+c.getSimpleName()+"{\n");        for(Field field:fields){            sb.append("\t"+Modifier.toString(field.getModifiers()));  //获取属性修饰符            sb.append("\t"+field.getType().getSimpleName());  //获取属性类型            sb.append("\t"+field.getName());  //获取属性名            sb.append(";\n");        }        sb.append("}\n");        System.out.println(sb);    }//getDeclaredFields方法示例public static void printFields(Class c){        Field[] fields=c.getDeclaredFields();        StringBuffer sb=new StringBuffer();        sb.append(Modifier.toString(c.getModifiers())+"\t"+c.getSimpleName()+"{\n");        for(Field field:fields){            sb.append("\t"+Modifier.toString(field.getModifiers()));  //获取属性修饰符            sb.append("\t"+field.getType().getSimpleName());  //获取属性类型            sb.append("\t"+field.getName());  //获取属性名            sb.append(";\n");        }        sb.append("}\n");        System.out.println(sb);}

2.2 根据名字获取特定属性的方法同样有两个,如下:

//该方法返回一个Field对象,该Field对象反射了name所指定的public属性//第一步,该方法在当前类中查找是否存在name指定的public属性;//第二步,如果在第一步中没有找到,那么将会从当前类所直接实现的接口中查找name指定的属性,查找接口顺序按照声明接口的顺序;//第三步,如果在第二部中还没有找到,那么将会递归地从当前类的父类中查找;//如果上述过程均未找到,那么将会抛出NoSuchFieldException异常public Field getField(String name)//返回Class对象所代表的类中指定name的Field对象//如果没有找到,将会抛出NoSuchFieldException异常public Field getDeclaredField(String name)

上述两个方法的示例如下:

//getField(String name)方法示例public static void printSpecificFields(Class c,String name) throws Exception{        Field field=c.getDeclaredField(name);        StringBuffer sb=new StringBuffer();        sb.append(Modifier.toString(field.getModifiers()));  //获取属性修饰符        sb.append("\t"+field.getType().getSimpleName());  //获取属性类型        sb.append("\t"+field.getName());  //获取属性名        sb.append(";\n");        System.out.println(sb);}
3. 获取成员方法

获取成员方法的函数也分为两类:一类是获取所有方法,另一类是根据参数获取特定的方法;

3.1 获取所有成员方法的函数有两个,如下:

//返回反射出Class对象所代表的类中所有public方法的Method数组,递归遍历其父类直至Obejct类中的所有public方法public Method[] getMethods()//返回Class对象所代表的类中声明的publicprotectedprivatedefault方法,但是不包含继承而来的方法public Method[] getDeclaredMethods()

上述两个方法的应用示例如下:

//getMethods方法示例public static void printMethods(Class c){        Method[] methods=c.getMethods();        StringBuffer sb=new StringBuffer();        sb.append(Modifier.toString(c.getModifiers())+"\t"+c.getSimpleName()+"{\n");        for(Method method:methods){            sb.append("\t"+Modifier.toString(method.getModifiers())+"\t");            sb.append(method.getReturnType().getSimpleName()+"\t");            sb.append(method.getName()+"()\n");        }        sb.append("}\n");        System.out.println(sb);    }//getDeclaredMethods方法示例    public static void printMethods(Class c){        Method[] methods=c.getDeclaredMethods();        StringBuffer sb=new StringBuffer();        sb.append(Modifier.toString(c.getModifiers())+"\t"+c.getSimpleName()+"{\n");        for(Method method:methods){            sb.append("\t"+Modifier.toString(method.getModifiers())+"\t");            sb.append(method.getReturnType().getSimpleName()+"\t");            sb.append(method.getName()+"()\n");        }        sb.append("}\n");        System.out.println(sb);    }

3.2 获取特定方法函数有两个,如下:

//返回反射出Class对象所代表的类中指定public方法的Method对象//name参数代表方法的名字//parameterTypes参数代表方法的指定参数类型次序//如果在当前类中没有找到,递归地从父类中查找指定的方法;public Method getMethod(String name, Class<?>... parameterTypes)//从Class对象所代表的类中返回指定的方法所对应的Method对象public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

上述两个方法的示例如下:

//getMethod(String name, Class<?>... parameterTypes)方法示例public static void invokeSpecialMethod(Class<?> c,String methodName,Object[] args){        Class<?>[] argsClasses=new Class<?>[args.length];        for(int i=0;i<args.length;i++){            argsClasses[i]=args[i].getClass();        }        try{            Method method=c.getMethod(methodName, argsClasses);            Object o=c.newInstance();            method.invoke(o, args);        }catch(Exception e){            System.out.println("getMethod error");        }    }//getDeclaredMethod(String name, Class<?>... parameterTypes)方法示例public static void invokeSpecialMethod(Class<?> c,String methodName,Object[] args){        Class<?>[] argsClasses=new Class<?>[args.length];        for(int i=0;i<args.length;i++){            argsClasses[i]=args[i].getClass();        }        try{            Method method=c.getDeclaredMethod(methodName, argsClasses);            Object o=c.newInstance();            method.invoke(o, args);        }catch(Exception e){            System.out.println("getMethod error");        }    }
4. 其他

待续。。。

原创粉丝点击