反射机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射机制相关的知识,希望对你有一定的参考价值。
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 }
以上是关于反射机制的主要内容,如果未能解决你的问题,请参考以下文章