1 什么是反射?
在Java中,反射(Reflection)是一种强大的工具,它允许程序在运行时(runtime)进行自我检查(introspection)和修改。通过反射,Java代码可以获取类的内部信息(如字段、方法、构造器等),并且可以动态地创建和操作这些类的实例。
简单来说:反射就是类在运行期间,把类中成员抽取为其他类的过程就是反射。
2 为什么使用反射?
反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法或属性。
例子:spring框架中只需要传入类的路径----spring框架就会帮你创建类的对象。 反射在许多框架和库中被广泛使用,如Spring、Hibernate等。这些框架使用反射来动态地加载和配置类,从而提供了高度的灵活性和可扩展性。
3 class类对象
每个类都有一个与之关联的Class对象。这个对象包含了类的元数据信息(metadata),如类的名称、包名、实现的接口、父类、字段、方法等。
3.1获得class反射类方式
第一种: 通过类名.class属性
Class<Student> aClass = Student.class;
第二种: 通过类路径获取
Class aClass1 = Class.forName("com.yzf.test.Student");
第三种: 通过对象名获取反射类型
Student student = new Student();
Class aClass2 = student.getClass();
3.2常用class方法
1.根据反射类得到实例对象 newInstance()
2.得到反射类上的注解对象。getAnnotation()
3.3获取类信息
使用反射,你可以获取类的字段、方法、构造器等信息。这些信息存储在Field
、Method
、Constructor
等类中。
①获取Method方法类对象:
getDeclaredMethods(): 得到本类中所有的方法。
getDeclaredMethod("方法名",参数类型):获取本类中指定的方法对象
getMethods():获取本类以及父辈类中public修饰的方法。
getMethod("方法名",参数类型):获取本类以及父辈类中指定public修饰的方法。
调用反射类方法:
//?通配符
Class<?> aClass = Class.forName("entity.Student");
Object o = aClass.newInstance();//实例对象
Method show = aClass.getMethod("show");
Object invoke = show.invoke(o);//.invoke调用实例对象中的方法
System.out.println(invoke);
System.out.println("----------------");
Method stu = aClass.getDeclaredMethod("stu",String.class);//带参
stu.setAccessible(true);//设置允许访问私有成员
Object invoke1 = stu.invoke(o,"语文");
System.out.println(invoke1);
②获取Filed属性对象对象:
getDeclaredFields();//得到本类中所有的属性
getDeclaredField("方法名",参数类型);//获取本类中指定的属性
getFields();//获取本类以及父辈类中public修饰的属性
getMethodFields("方法名",参数类型);//获取本类以及父辈类中指定public修饰的属性
属性对象赋值:
Class<Student> studentClass = Student.class;//获取反射类
Student student = studentClass.newInstance();//实例对象
Field[] declaredFields = studentClass.getDeclaredFields();//本类所有属性对象
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName());//getName()得到成员属性名
//自定义注解
myAnnotation annotation = declaredField.getAnnotation(myAnnotation.class);
//注解的值
System.out.println(annotation.value());
}
Field name = studentClass.getDeclaredField("name");//获取指定属性对象
name.setAccessible(true);//设置允许访问私有成员
name.set(student,"lll");//set方法赋值
System.out.println(student);
4 案例
在properties属性文件中指定类的路径,通过反射完成类对象的创建以及类中属性的赋值。
第一步:properties属性文件(类路径获取)
className=entity.Student
第二步:主函数测试
public class Test06 {
public static void main(String[] args) throws Exception{
//加载属性文件
InputStream inputStream=Test06.class.getClassLoader().getResourceAsStream("properties.properties");
//属性类对象
Properties properties=new Properties();
properties.load(inputStream);
//属性类读取属性文件中指定的key的值
String className= properties.getProperty("className");
//根据类路径得到反射对象
Class<?> aClass = Class.forName(className);
//反射类创建实例对象
Object o = aClass.newInstance();
System.out.println(o);
//该类所有方法
Field[] declaredFields = aClass.getDeclaredFields();
//遍历赋值
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);//设置允许访问私有成员
declaredField.set(o,new Random().nextInt(10)+"");
}
System.out.println(o);
}
}