JVM为每一个class,创建了一个class实例,这个class实例包含class的所有信息
通过class实例,来获取class信息的方法就是反射
1. 获取class实例的三种方式
方法一:通过类名获取
Class cls = 类名.class
方法二:通过实例对象获取
Class cls = 实例化对象.getClass()
方法三:通过完整类名获取
Class cls = Class.forName("完整类名");
获取父类class实例
Class cls = class实例.getSuperclass();
获取所有类实现接口的class实例(不包括继承的接口)
Class[] clss = class实例.getInterfaces();
2. 通过class实例获取class信息
- 获取字段的信息
获取字段实例(包含父类):Field f = class实例.getField("字段名称")
获取字段实例(不包含父类,当前类):Field f = class实例.getDeclaredField("字段名称")
获取所有字段实例(包含父类):Field f = class实例.getFields()
获取所有字段实例(不包含父类,当前类):Field f = class实例.getDeclaredFields()
根据字段实例可获取和设置当前字段的相关信息
获取字段的名称:String fName = f.getName();
获取字段的值:Object fValue = f.get();
设置字段的值:f.set(class实例, 设置的值);
设置非public字段的值需要调用:
f.setAccessible(true); // 修改非public字段,需要首先调用setAccessible(true)方法
获取字段的类型:String fType = f.getType();
获取字段的修饰符类型(int):int fModifier = f.getModifiers();
- 获取方法的信息
获取方法实例(包含父类):Method m = class实例.getMethod("方法名称",参数类型.class)
获取方法实例(不包含父类,当前类):Method m = class实例.getDeclaredMethod("方法名称",参数类型.class)
获取所有字段实例(包含父类):Method[] m = class实例.getMethods()
获取所有字段实例(不包含父类,当前类):Method[] m = class实例.getDeclaredMethods()
根据方法实例可获取当前方法的相关信息
获取方法的名称:String MName = m.getName();
获取方法返回值类型(结果也是一个class实例):class type = m.getReturnType
获取方法参数类型(结果也是一个class数组实例):class[] types = m.getReturnType
获取方法的修饰符类型(int):int fModifier = m.getModifiers();
调用实例方法(有返回值的方法):返回值类型 mr = (返回值类型) m.invoke(class实例,参数列表);
调用实例方法(无返回值的方法):m.invoke(class实例);
调用静态方法(有返回值的方法):返回值类型 mr = (返回值类型) m.invoke(null,参数列表);
调用非public方法(有返回值的方法)需要调用:
m.setAccessible(true); // 修改非public方法,需要首先调用setAccessible(true)方法
构造方法(无父类概念)
获取构造方法(public修饰):Constructor c1 = m.getConstructor(参数类型.class);
获取构造方法(任意):Constructor c1 = m.getDeclaredConstructor(参数类型.class);
获取所有构造方法(public修饰):Constructor[] c1s = m.getConstructors();
获取所有构造方法(任意):Constructor[] c1s = m.getDeclaredConstructors();
调用构造方法:返回值类型 cr1 = (返回值类型) c1.newInstance(参数列表);
3. 反射创建对象
拓展:常规创建对象和使用反射创建对象
- 常规创建对象,使用new关键词创建一个新对象
特点:new: 强类型(不好回收)。相对高效。能调用任何public构造。
类名 实例化对象名称 = new 类名(参数列表);
- 反射创建对象,使用newInstance()方法创建(类的加载机制:必须加载过且已连接)(常用于工厂模式)
特点:newInstance: 弱类型(好回收)。低效率。只能调用无参构造。
class c = Class.forName("Example");
factory = (ExampleInterface)c.newInstance();
网友评论