一、什么是Java的反射机制
Java反射是Java被视为动态语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public,static等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。
换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。
java学习交流:737251827 可领取学习资源及对十年开发经验大佬提问,免费解答!
二、JDK中提供的Reflection API
Java反射机制相关的API在包java.lang.reflect中,参考JDK1.6.0的包了解其详细信息
Member接口
该接口可以获取有关类成员(域或者方法)或者构造函数的信息。
AccessibleObject类
该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。它提供了将反射的对象标记为在使用时取消默认Java语言访问控制检查的能力。
Array类
该类提供动态生成和访问Java数组的方法
Constructor类
提供一个类的构造函数的信息以及访问类的构造函数的接口
Field类
提供一个类的域的信息以及访问类的域的接口
Method类
提供一个类的方法的信息以及访问类的方法的接口
Modifier类
提供了static方法和常量,对类和成员访问修饰符进行解码
Proxy类
提供动态生成代理类和类实例的静态方法
三、Java的反射机制提供了什么功能
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法
在运行时创建新类对象
在使用Java反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象
1.获取类的Class对象
Class类的实例表示正在运行的Java应用程序中的类和接口。
获取类的Class对象有多种方式:
调用getClass
Boolean var1 = true;
Class<?> classType2 = var1.getClass();
System.out.println(ClassType2);
输出:class java.lang.Boolean
运用.class语法
Class<?> classType4 = Boolean.class;
System.out.println(classType4);
输出:class java.lang.Boolean
运用static method Class.forName()
Class<?> classType5 = Class.forName("java.lang.Boolean");
System.out.println(classType5);
输出:class java.lang.Boolean
运用primitive wrapper classes的TYPE语法
这里返回的是原生类型,和Boolean.class返回的不同
Class<?> classType3 = Boolean.TYPE;
System.out.println(classType3);
输出:boolean
2.获取类的Fields
可以通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值。
JAVA的Class<T>类提供了几个方法获取类的属性。
public Field getField(String name)
返回一个Field对象,它反映此Class对象所表示的类或接口的指定公共成员字段
public Field[] getFields()
返回一个包含某些Field对象的数组,这些对象反映此Class对象所表示的类或接口的所有可访问公共字段
public Field getDeclaredField(String name)
返回一个Field对象,该对象反映此Class对象所表示的类或接口的指定已声明字段
public Field[] getDeclaredFields()
返回Field对象的一个数组,这些对象反映此Class对象所表示的类或接口所声明的所有字段
3.获取类的Method
通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法
Class<T>提供了几个方法获取类的方法
public Method getMethod(String name,Class<?>...parameterTypes)
返回一个Method对象,它反映此Class对象所表示的类或接口的指定公共成员方法
public Method[] getMethods()
返回一个包含某些Method对象的数组,这些对象反映此Class对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共member方法
public Method getDeclaredMethod(String name,Class<?>...parameterTypes)
返回一个Method对象,该对象反映此Class对象所表示的类或接口的指定已声明方法
public Method[] getDeclaredMethods()
返回Method对象的一个数组,这些对象反映此Class对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法
4.获取类的Constructor
通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例
Class<T>类提供了及格方法获取类的构造器。
public Constructor<T> getConstructor(Class<?>...parameterTypes)
返回一个Constructor对象,它反映此Class对象所表示的类的指定公共构造方法
public Constructor<?>[] getConstructors()
返回一个包含某些Constructor对象的数组,这些对象反映此Class对象所表示的类的所有公共构造方法
public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes)
返回一个Constructor对象,该对象反映此Class对象所表示的类或接口的指定构造方法
public Constructor<?>[] getDeclaredConstructors()
返回Constructor对象的一个数组,这些对象反映此Class对象表示的类声明的所有构造方法。它们是公共、保护、默认(包)访问和私有构造方法
5.新建类的实例
通过反射机制创建新类的实例,有几种方法可以创建
调用无自变量ctor
1、调用类的Class对象的newInstance方法,该方法会调用对象的默认构造器,如果没有默认构造器,会调用失败
Class<?> classType = ExtendType.class;
Object inst = classType.newInstance();
System.out.println(inst);
输出:
Type:Default Constructor
ExtendType:Default Constructor
com.yeqc.testDemo01.ExtendType@2a139a55
2、调用默认Constructor对象的newInstance方法
Class<?> classType = ExtendType.class;
Constructor<?> constructor1 = classType.getConstructor();
Object inst = constructor1.newInstance();
System.out.println(inst);
调用带参数ctor
3、调用带参数Constructor对象的newInstance方法
Constructor<?> constructor2 = classType.getDeclaredConstructor(int.class,Sting.class);
Object inst = constructor2.newInstance(1,"123");