Java学习之反射

Java 反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法。
对于任意一个对象,都能够调用它的任意一个方法和属性

反射实际要做的动作
1、加载指定的class文件,并创建Class对象
2、实例化对象
3、通过实例化对象获取字段对象,并对字段对象的设置和获取
4、通过实例化对象获取方法对象,并对方法进行调用

 一、加载指定的class文件,并创建Class对象

有三种方式

 1     /*
 2      * 获取字节码对象的方式三、
 3      * 根据类的全名称获取该类
 4      */
 5     public static void forNameObject() throws ClassNotFoundException {    
 6     String className="cn.marw.bean.Person";
 7     Class clazzClass=Class.forName(className);
 8     }
 9     
10     /*
11      * 获取字节码对象的方式二、
12      * 任何数据类型都具备一个静态的属性.class来获取其对象的class对象
13      * 必须明确类
14      */
15     public static void classObject() {    
16     Class clazzClass=Person.class;    
17     }
18     
19     /*
20      * 获取字节码对象的方式一
21      * Object类中的getClass方法
22      * 必须明确具体的类,并创建对象
23      */
24     public static void getClassObject() {
25     Person p=new Person();
26     Class clazzClass=p.getClass();
27     Person p1=new Person();
28     Class clazzClass1=p1.getClass();
29     }

二、实例化对象

有两种方式:

 1     /*
 2      * 方式二、
 3      * 有参构造函数实例化
 4      */
 5     public static void createParamNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException {    
 6     
 7     //cn.marw.bean.Person p = new cn.marw.bean.Person("小明",29);
 8     
 9     //相当于以下代码
10     String className="cn.marw.bean.Person";
11     Class clazzClass=Class.forName(className);
12     /*
13      * 获取构造函数对象
14      * 
15      * 所有公共构造函数
16      * getConstructor();
17      * 获取所有访问权限(public、private)的构造函数(Declared:无视访问权限18      * getDeclaredConstructor();
19      * 
20      * 获取指定公共(public)构造函数,因为构造函数名都时一样的,所以只需要查看构造函数的参数列表的类型22      * getConstructor(parameterTypes);
23      * getDeclaredConstructor(parameterTypes);
24      * 
25      * parameterTypes:构造函数的参数列表中参数类型对应的字节码对象27      * 如:String => String.class
28      */
29     Constructor constructor=clazzClass.getConstructor(String.class,int.class);
30     
31     /*
32      * 通过该构造器对象的newInstance方法进行对象的初始化
33      */
34     Object object=constructor.newInstance("小明",29);
35     }
36     /*
37      * 方式一、
38      * 无参构造函数实例化
39      */
40     public static void createNewObject() throws Exception {    
41     //
42     cn.marw.bean.Person p = new cn.marw.bean.Person();
43     //相当于以下代码
44     String className="cn.marw.bean.Person";
45     Class clazzClass=Class.forName(className);
46     /*
47      * newInstance():创建此Class对象所表示的类的一个新实例。如同一个带有空参列表的实例化
48      * 如果没有Person类没有空参构造函数时,InstantiationException
49      */
50     Object obj = clazzClass.newInstance();
51     }

三、对象字段

 1     private static void getFieldDemo() throws Exception {
 2     Class clazz=Class.forName("cn.marw.bean.Person");
 3     //只能获取共有的字段,包含父类的共有字段
 4     //Field field=clazz.getField("age");
 5     //只能获取本类所有字段
 6     field = clazz.getDeclaredField("age");
 7     /*
 8      * 对私有字段的访问取消权限检查。暴力访问
 9      */
10     field.setAccessible(true);
11         /*
12          * cn.marw.bean.Person person= new cn.marw.bean.Person();
13          * person.age=30;
14          * 访问字段必须是对象
15          * field.get(Object);//指定字段所属的对象
16          */
17     Object object=clazz.newInstance();
18     field.set(object, 28);
19     field.get(object);
20     }

四、对象函数

 1     private static void getMethodDemo() throws Exception {
 2     Class clazz = Class.forName("cn.marw.bean.Person");
 3     /*
 4      * 获取共有的方法,包括父类
 5      */
 6     Method[] methods = clazz.getMethods();
 7 
 8     /*
 9      * 获取本类所有方法,不包含父类
10      */
11     methods = clazz.getDeclaredMethods();
12     for (Method method : methods) {
13         System.out.println(method);
14     }
15     /*
16      * 获取对象
17      */
18     Constructor constructor = clazz.getConstructor(String.class,int.class);
19     Object obj = constructor.newInstance("小明",25);
20     /*
21      * 获取指定方法
22      */
23     Method method = clazz.getMethod("show",null);
24     /*
25      * 函数调用
26      */
27     method.invoke(obj, null);
28     
29     /*
30      * 获取对象
31      */
32     obj=clazz.newInstance();
33     /*
34      * 获取指定有参函数
35      * 1、指定方法名
36      * 2、参数列表类型对应的字节码对象
37      */
38     method = clazz.getMethod("paramMethod",String.class,int.class);    
39     /*
40      * 函数调用
41      * 1、函数所属对象
42      * 2、参数列表对应内容
43      */
44     method.invoke(obj, "小强",22);
45     }

猜你喜欢

转载自www.cnblogs.com/WarBlog/p/12155234.html