什么是反射
反射就是程序在运行中能够获取自身的信息
为什么要使用反射
反射主要用于编写框架中
获得Class对象的三种方式
-
通过类名.class实现
// 通过类名.class实现 Class<Dog> dogClass = Dog.class;
-
使用对象.getClass()实现
Dog dog = new Dog(); // <? extends Dog> 指定类型上限 Class<? extends Dog> dogClass = dog.getClass();
-
使用Class.forName(类型全名称)
// 使用Class.for(全限定类名) Class<?> aClass = Class.forName("com.xww.reflect.Dog"); // System.out.println(aClass);
反射创建对象的两种方式
通过Class对象来实例化(要求必须有公共的无参构造)
步骤:
-
获取该类型的Class对象
-
创建对象(调用newInstance()方法)
// 1. 获取该类型的Class对象 Class<Dog> dogClass = Dog.class; // 2. 创建对象 Dog dog = dogClass.newInstance(); System.out.println(dog);
通过获得构造器对象来实例化
步骤:
-
获得该类型的Class对象
-
获得该类型的构造器对象(getConstructor())
-
创建对象
// 1. 获得该类型的Class对象 Class<Dog> dogClass = Dog.class; // 2. 获得该类型的构造器对象 //获得有参构造 Constructor<Dog> dogConstructor1 = dogClass.getConstructor(); //获得有参构造方法 Constructor<Dog> dogConstructor2 = dogClass.getConstructor(String.class, int.class); // 3. 创建对象 // 无参创建 Dog dog1 = dogConstructor1.newInstance(); Dog dog2 = dogConstructor2.newInstance("小黑", 3); System.out.println(dog1); System.out.println(dog2);
使用反射操作对象的属性
步骤:
-
获得该类型的Class对象
-
创建对象
-
获得属性对象
-
设置属性值
// 1. 获得该类型的Class对象 Class<Dog> dogClass = Dog.class; // 2. 创建对象 Dog dog = dogClass.newInstance(); // 3. 获得属性对象 // 注意:getDeclaredFields() 与 getFields() 的区别 // 前者能够获得本类的所有的属性,后者能获得本类及父类的公共属性,私有属性不能获得 Field[] fields = dogClass.getDeclaredFields(); // Field[] fields = dogClass.getFields(); // 4. 设置属性值 for (Field field : fields) { // 获得属性名 String fieldName = field.getName(); // 获得属性类型 Class<?> type = field.getType(); // 私有属性不能直接访问,需要改变访问权限 field.setAccessible(true); // 对属性进行赋值 if (fieldName.equals("name") && type == String.class) { field.set(dog,"小黑"); } if (fieldName.equals("age") && type == int.class){ field.set(dog,3); } } System.out.println(dog);
使用反射操作对象的方法
步骤:
-
获得该类型的Class文件
-
创建对象
-
获得该对象的方法
-
调用执行方法
// 1. 获得该类型的Class文件 Class<Dog> dogClass = Dog.class; // 2. 创建对象 Dog dog = dogClass.newInstance(); // 3. 获得该对象的方法 Method sayHello = dogClass.getMethod("sayHello"); // 4. 调用执行方法 sayHello.invoke(dog);