.1.什么是反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

2.类加载的过程

  • JAVA中的类初始化分为三个步骤:加载连接初始化。这三个步骤统称为类的加载或类初始化。
  • 所谓类的加载是指将class文件读入内存,并为之创建一个java.lang.Class对象,也就是所当程序使用任何类,都将会为之建立一个java.lang.Class对象。

JAVA程序在运行期间可以动态加载、解析和使用一些在编译阶段并不确定的类型,这一机制被称为发射(Reflection), 反射机制提供的功能: 1.在运行时判断任意一个对象所属的类。 2.在运行时构造任意一个类的对象。 3.在运行时判断任意一个类所具有的成员变量和方法。 4.在运行时调用任意一个对象的方法

3、反射API

  • 1.获取Class方法
		//1.在一个对象被创建的情况下,获取Class方法
		Dog dog=new Dog();
		Class clazz1 = dog.getClass();
		//2.在一个类被加载到内存中,但是还没有创建对象的情况下,获取Class方法
		Class clazz2=Dog.class;
		//3.在一个类还没有被加载情况下,获取Class的方法
		Class clazz3= Class.forName("Reflect.Dog");
  • 2.创建对象

    平常情况我们通过new Object来生成一个类的实例,但有时候我们没法直接new,只能通过反射动态生成。可以通过提供的newInstance()方法生成,或者调用类的构造函数。

Dog dogg = (Dog)clazz2.newInstance();
Dog dogg1 = (Dog)clazz1.getConstructor().newInstance();
  • 3.Method类
		//返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口
		Method[] methods = clazz1.getMethods();
		//返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法
		Method setName = clazz1.getMethod("setName", String.class);
		//包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
		Method[] declaredMethods = clazz1.getDeclaredMethods();
		//返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法
		Method getName = clazz1.getDeclaredMethod("getName");
		

简单来说:有 Declared 的就是获取当前类的所有方法(包括privatepublicprotect),没有的就获取自己已经继承的public方法。

方法的执行: setName.invoke(dog, "我是小狗"); Class对象.invoke(执行对象,可变参数);

  • 4.Field类 同理,这个是获取变量的。
		//获取本类或者继承类的公有变量
		Field[] fields = clazz3.getFields();
		//获取本类或者继承类的 某个 公有变量
		Field field = clazz1.getField("xxx");
		//获取本类的全部公有私有变量
		Field[] declaredFields = clazz1.getDeclaredFields();
		//获取本类的 某个 公有私有变量
		Field declaredField = clazz1.getDeclaredField("num");

设置值以及获取值

		//设置值,私有的必须设置访问权限为可达
        declaredField.setAccessible(true);
		declaredField.setInt(dog, 25);
							//获取值
		System.out.println(declaredField.get(dog));

注意:这里设置值前提是变量的访问权限不能是private,否则会报错:Class Reflect.Reflect can not access a member of class Reflect.Dog with modifiers "private"。私有的变量应该使用内部的setter 方法设置值。

4.获取私有属性值

有些时候,再一些开源项目中定义好的类,里面有我们需要的属性,但是没有直接的获取的方式,并且是私有的,可以通过反射进行获取。

示例:

Dog dog=new Dog(1, "dog");
Class clazz2=Dog.class;
        
Field field = clazz2.getDeclaredField("name");
field.setAccessible(true); //必须
String dogName = (String) field.get(dog);
System.out.println(dogName);

如果需要使用到类型判断

Field[] declaredFields1 = clazz2.getDeclaredFields();
for (Field field1 : declaredFields1) {
    field1.setAccessible(true);
    Class<?> type = field1.getType();
    // Class 类型比较,包装类和基本数据类型
    if (int.class == type || String.class == type) {

    } else if (Number.class.isAssignableFrom(type)) {
    // isAssignableFrom 前者类型和后者是否相同,或者是它的超类
    }
}
上次更新时间: 2024/5/7 05:59:02