反射机制(java.Reflection)
反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息,并且能操作任意对象的的属性和方法。加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象包含了完整的类的结构信息,就可以通过这个对象看到对应的类的结构。
获取Class类的实例
-
如果已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
Class c1 = Person.class;
-
已知某个类的实例,调用该实例的getClass()方法获取Class对象
Class c1 = person.getClass();
-
已知一个类的全限定名,可通过Class类的静态方法forName()获取,会抛出ClassNotFoundException
Class c1 = Class.forName("com.wx.dojo.Person");
-
利用ClassLoader
获取类的运行时结构
-
获取类的属性
// 可以获取所有的属性 Field[] declaredFields = aClass.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField); } // 只能找到public属性 Field[] fields = aClass.getFields(); for (Field field : fields) { System.out.println(field); }
-
获取类的方法
// 获取本类以及父类的所有public方法 Method[] methods = aClass.getMethods(); //获取本类的所有方法 Method[] declaredMethods = aClass.getDeclaredMethods();
动态创建对象执行方法
创建一个Category的类,如下:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Category {
private int id;
private String name;
private void sell(){
System.out.println("sell" + this.name);
}
}
-
通过无参构造器创建一个对象
/** * 通过无参构造器创建一个对象 */ Class aClass = category.getClass(); Category instance = (Category) aClass.newInstance(); System.out.println(instance); /** *结果: * Category(id=0, name=null) */
-
没有无参构造器的时候通过有参构造器获取对象
/** * 当类没有无参构造的时候通过获取有参构造器创建对象 */ Constructor constructor = aClass.getDeclaredConstructor(int.class, String.class); Category instance1 = (Category) constructor.newInstance(1,"香蕉"); System.out.println(instance1); /** * 结果: * Category(id=1, name=香蕉) */
-
调用对象的方法
/** * 通过反射调用普通方法 */ Method setId = aClass.getDeclaredMethod("sell"); // 设置私有的方法可以被访问 setId.setAccessible(true); // 激活方法 setId.invoke(instance1); /** * 结果: * sell香蕉 */
-
操作对象的属性
/** * 通过反射操作属性 */ Field name = aClass.getDeclaredField("name"); // 设置私有的属性可以被访问 name.setAccessible(true); name.set(instance,"apple"); System.out.println(instance.getName());