首页 > 代码库 > 反射机制

反射机制

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

对于任意一个对象,都能调用他的任意一个属性和方法。

这种动态获取的信息以及动态调用对象的方法的功能成为java语言的反射机制。

 

简单说:动态获取类中信息,就是反射机制,可以理解为对类的解剖。

 

想要对一个类进行解剖,只要获取到该类的字节码文件对象即可,即  .class文件

获取Class对象的三种方式:

第一种方式:Object类中的getClass()方法

第二种方式:任何数据类型都有一个静态的属性.calss来获取对应的class对象。

第三种方式:Class类中有一个forName()方法,只要给定类的字符串名称就可以获取该类。

 

 1 public static void main(String[] args) throws ClassNotFoundException { 2              3         getClassObject_3(); 4      5     } 6     /* 7      * 方式三: 8      * 只要通过给定的类的 字符串名称就可以获取该类,更为扩展。 9      * 可是用Class类中的方法完成。10      * 该方法就是forName.11      * 这种方式只要有名称即可,更为方便,扩展性更强。 12      */13     14     public static void getClassObject_3() throws ClassNotFoundException {15         16         String className = "cn.itcast.bean.Person";17         18         Class clazz = Class.forName(className);19         20         System.out.println(clazz);21     }22     23     24 25 26 27     /*28      * 方式二:29      * 2,任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。30      * 相对简单,但是还是要明确用到类中的静态成员。31      * 还是不够扩展。 32      * 33      */34     public static void getClassObject_2() {35         36         Class clazz = Person.class;37         38         Class clazz1 = Person.class;39         System.out.println(clazz==clazz1);40     }41     42     /*43      * 获取字节码对象的方式:44      * 1,Object类中的getClass()方法的。45      * 想要用这种方式,必须要明确具体的类,并创建对象。46      * 麻烦 .47      * 48      */49     public static void getClassObject_1(){50         51         Person p = new Person();52         Class clazz = p.getClass();53         54         Person p1 = new Person();55         Class clazz1 = p1.getClass();56         57         System.out.println(clazz==clazz1);58     }

 

如何产生对象:

 

 1 public static void createNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException{ 2          3          4         //早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存, 5 //        并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象. 6 //        cn.itcast.bean.Person p = new cn.itcast.bean.Person(); 7          8         //现在: 9         String name = "cn.itcast.bean.Person";10         //找寻该名称类文件,并加载进内存,并产生Class对象。11         Class clazz = Class.forName(name);12         //如何产生该类的对象呢?13         Object obj  = clazz.newInstance();14         15         16         17         18     }

 

获取构造函数:

 1 public static void createNewObject_2() throws Exception { 2          3 //        cn.itcast.bean.Person p = new cn.itcast.bean.Person("小强",39); 4          5         /* 6          * 当获取指定名称对应类中的所体现的对象时, 7          * 而该对象初始化不使用空参数构造该怎么办呢? 8          * 既然是通过指定的构造 函数进行对象的初始化, 9          * 所以应该先获取到该构造函数。 通过字节码文件对象即可完成。10          * 该方法是:getConstructor(paramterTypes);11          * 12          */13         String name = "cn.itcast.bean.Person";14         //找寻该名称类文件,并加载进内存,并产生Class对象。15         Class clazz = Class.forName(name);16         //获取到了指定的构造函数对  象。17         Constructor constructor = clazz.getConstructor(String.class,int.class);18         19         //通过该构造器对象的newInstance方法进行对象的初始化。20         Object obj = constructor.newInstance("小明",38);21         22             23         24     }

 

获取字段:

 1 /* 2      * 获取字节码文件中的字段。 3      */ 4     public static void getFieldDemo() throws Exception { 5          6         Class clazz = Class.forName("cn.itcast.bean.Person"); 7          8         Field field = null;//clazz.getField("age");//只能获取公有的, 9         10         field = clazz.getDeclaredField("age");//只获取本类,但包含私有。 11         12         //对私有字段的访问取消权限检查。暴力访问。13         field.setAccessible(true);14         15         Object obj = clazz.newInstance();16         17         field.set(obj, 89);//要先有对象才能设置字段值,所以要先创建实例才能设置字段值。18         19         20         Object o = field.get(obj);21         22         System.out.println(o);23         24 //        cn.itcast.bean.Person p = new cn.itcast.bean.Person();25 //        p.age = 30;26         27     }

 

获取Class中的方法:

/*     * 获取指定Class中的所有公共函数。     */    public static void getMethodDemo() throws Exception {                Class clazz = Class.forName("cn.itcast.bean.Person");                Method[] methods  = clazz.getMethods();//获取的都是公有的方法。         methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有。         for(Method method : methods){            System.out.println(method);        }                    }

 

获取方法的时候必须指定方法名即参数列表。

 

//获取空参数的方法

 1 public static void getMethodDemo_2() throws Exception { 2          3         Class clazz = Class.forName("cn.itcast.bean.Person"); 4          5         Method method = clazz.getMethod("show", null);//获取空参数一般方法。 6          7 //        Object obj = clazz.newInstance();空参构造函
8 Constructor constructor = clazz.getConstructor(String.class,int.class); 9 Object obj = constructor.newInstance("小明",37);10 11 //方法运行必须有对象,对象必须指定用哪个构造函数来创建。12 method.invoke(obj, null);13 14 15 16 }

 

有参数列表的方法:

 1 public static void getMethodDemo_3() throws Exception { 2          3         Class clazz = Class.forName("cn.itcast.bean.Person"); 4          5         Method method = clazz.getMethod("paramMethod", String.class,int.class); 6          7         Object obj = clazz.newInstance(); 8          9         method.invoke(obj, "小强",89);10         11         12     }

 

反射机制