什么是反射?
反射是Java语法的一种高级特性,在"运行期间"对Java的类型信息进行检查,操作处理。
例如:加载JDBC驱动类、MyBatis动态处理resultType、Spring根据配置信息创建Bean对象等使用场景。
反射中的类
Class类
定义:Class对象用于保存一个类的类型信息,它是反射的入口操作。
获取Class对象的三种方式:
- 通过类名
- 通过forName()方法
- 通过对象
Constructor类
定义:代表一个类中的构造方法(构造器),用于创建“目标”对象。
获取Constructor构造方法的方式:
- 获取无参构造方法:Class对象.getConstructor()
- 获取有参构造方法: Class对象.getConstructor(Class…)
执行Constructor构造方法的方式:
- 执行无参构造方法:Constructor对象.newInstance()
- 执行有参构造方法:Constructor对象.newInstance(值…)
Field类
定义:代表一个类中的成员变量(字段),用于为“目标对象”保存值和获取值。
获取Field成员变量的方式:
获取所有成员变量
- public修饰的成员变量:Class对象.getFields()
- public\private修饰的成员变量:Class对象.getDeclaredFields()
获取指定成员变量
- public修饰的成员变量:Class对象.getField(成员变量名称)
- public\private修饰的成员变量:Class对象.getDeclaredField(成员变量名称)
**使用Field成员变量的方法:**Field对象.setXXX(目标对象,值)
Method类
定义:代表一个类中的方法,用于调用执行该方法。
获取Method方法的方式:
- Class对象.getMethod()
- Class对象.getMethods()
**执行Method方法的方式:**Method对象.invoke(目标对象,方法参数)
常见的反射操作包括:
- 获取Class类型信息
- 执行构造方法创建对象
- 调用实例方法
- 通过成员变量保存值和获取值
获取Class类型信息(常见的三种方法)
1.通过类名获取
Class bookClass1=Book.class;
2.通过forname方法
Class bookClass2=Class.forName("反射.Book");
3.通过对象获取
Class bookClass3 = new Book().getClass();
执行构造方法创建对象(常见的三种方法)
1.通过Class对象(调用无参构造方法)
Object newInstance1 = bookClass.newInstance();
2.通过构造方法(无参构造方法)
Constructor constructor1=bookClass.getConstructor();
Object newInstance2 = constructor1.newInstance();
3.通过构造方法(有参构造方法)
Constructor constructor2=bookClass.getConstructor(String.class,String.class,double.class,int.class);
Object newInstance3 = constructor2.newInstance("张三","李四",100.0,100);
调用实例方法
1.获取所有方法(Method对象的数组)
Method[] methods = bookClass.getMethods();
2.获取方法的作用(完整代码)
public class Test05 {
public static void main(String[] args) throws ClassNotFoundException {
// 获取book类的class对象
Class bookClass = Class.forName("反射.Book");
//获取方法(所有)
Method[] methods = bookClass.getMethods();
for(Method m:methods) {
System.out.println(m);
System.out.println("訪問修飾符"+m.getModifiers());
System.out.println("返回值類型"+m.getReturnType());
System.out.println("參數列表"+m.getParameters());
System.out.println("方法名"+m.getName());
}
}
}
通过成员变量保存值和获取值
这里使用完整的案例说明(我是写了一个方法进行获取)
public class Test04 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException,
InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// 获取book类的class对象
Class bookClass = Class.forName("反射.Book");
// 通过构造方法有参
Constructor constructor2 = bookClass.getConstructor(String.class, String.class, double.class, int.class);
Object newInstance3 = constructor2.newInstance("张三", "李四", 100.0, 100);
show(newInstance3);
}
public static void show(Object obj) {
try {
Class class1 = obj.getClass();
Field[] fields = class1.getDeclaredFields();
for (Field f : fields) {
f.setAccessible(true);
System.out.println("属性:" + f.getName());
System.out.println("值:" + f.get(obj));
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}