文章目录
- 1. 什么是反射
- 2. Java中类加载的三个阶段
- 3. 反射机制提供的相关类
- 4. Java中获取Class类的三种方式
- 5. Class类提供的功能
- 5.1. 获取Field类方法
- 5.2. 获取Method类方法
- 5.3. 获取Constructor类方法
- 5.4. Class中其他方法
1. 什么是反射
Java中的反射主要是体现在运行期间
,让程序在运行期间可以动态获取Java中的类,属性,方法,构造方法,以及注解等功能
,以及可以在运行期间动态的设置或调用属性,方法,构造方法,注解等功能
,总结来说反射机制就是可以在运行期间动态的获取对象的所有信息并且更改执行的代码。
Java的反射是在运行期间操作的功能,这种功能被称为Java反射机制
编程语言一般分为两种:1. 弱类型语言
,2. 强类型语言
- 弱类型语言:
- 弱类型语言是指定义变量时的类型可以动态修改,变量没有固定的数据类型,一个变量可以赋值任意数据类型(JDK11后Java也支持弱类型)
- 强类型语言:
- 强类型语言是指定义变量时的类型已被确认,无法修改类型,类型不会因为数据赋值而改变(JDK1.8就是强类型语言)
- Java的反射机制早起出现就是为了弥补强类型语言中的数据类型固定的问题,以及Java底层运行方式
Java运行的步骤也是反射机制的体现:通过编译器将.java
文件编译成.class
字节码文件,再通过JVM
将.class
字节码文件加载进内存在堆中生成对应的Class对象,JVM在加载.class
文件时就是使用的反射机制.
2. Java中类加载的三个阶段
Java中类加载分为三个阶段:1. 源代码
,2. 类加载
,3. 运行时
- 源代码(source)
- 源代码是指编译后的
.class
文件,经过编译后的.class
字节码文件就是源代码
- 源代码是指编译后的
- 类加载(class)
- 类加载是将
.class
文件通过类加载器加载到虚拟机中运行,类加载器解析.class
文件生成的Class
对象
- 类加载是将
- 运行时(runtime)
- 当运行期间调用它
newInstance()
方法时会根据Java的类型生成对应的对象,并开始执行代码
- 当运行期间调用它
3. 反射机制提供的相关类
java提供的与反射有关的类都在java.lang.reflect包中
反射机制提供的相关类是用于在运行期间动态的获取或设置内容,提供了类,属性,方法,构造方法等功能
Class
:获取当前对象的类(当前类的全限定名称–>从包名到类名的全名称)- Class类功能是可通过Class类创建对象的实例,并且类中的
Constructor,Method,Field
这些类都是通过Class类获取
- Class类功能是可通过Class类创建对象的实例,并且类中的
Constructor
:获取当前类中的构造方法(可以获取包括private修饰的)- 用于获取构造方法后调用构造方法创建对象实例
Method
:获取当前类中的方法(可以获取包括private修饰的)- 用于获取方法后调用此方法
Field
:获取当前类中的属性(可以获取包括private修饰的)- 用于获取属性后设置或获取属性的数据
- 用于获取属性后设置或获取属性的数据
4. Java中获取Class类的三种方式
Java中提供了三种方式获取Class类:
- 创建对象并调用Object提供的getClass方法获取
- 通过
类名.class
获取–>一般用于方法参数使用 - 通过Class类的静态方法
Class.forName("类的全限定名称")
:获取–>可用于动态创建或加载对象使用public static void main(String[] args) throws ClassNotFoundException { // 1. 创建对象并调用Object类的getClass方法 Demo demo = new Demo(); Class<? extends Demo> clazz1 = demo.getClass(); System.out.println("getClass = " + clazz1); // 2. 通过类名.class获取Class类 Class<Demo> clazz2 = Demo.class; System.out.println("class = " + clazz2); // 3. 通过Class.forName("全限定名称")获取Class对象 Class<?> clazz3 = Class.forName("reflection.Demo"); System.out.println(".forName = " + clazz3); }
5. Class类提供的功能
通过Class类key获取Field
,Method
,Constructor
对象,通过这些对象可以调用或设置获取类中的数据
5.1. 获取Field类方法
public Field getDeclaredField(String name)
:通过属性名称获取指定属性,可以获取所有修饰符修饰的属性public Field[] getDeclaredFields()
:获取类中所有的属性,可以获取所有修饰符修饰的属性
// 通过Class.forName获取Class类
Class<?> clazz = Class.forName("reflection.User");
Field id = clazz.getDeclaredField("id");
System.out.println("id = " + id);
System.out.println("==================================");
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println("declaredField = " + declaredField);
}
5.2. 获取Method类方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
:通过方法名称以及形参列表类型获取指定方法,可以获取除父类之外的所有修饰符修饰的方法public Method[] getDeclaredMethods()
:获取类中的所有方法,可以获取除父类之外的所有修饰符修饰的方法
// 通过Class.forName获取Class类
Class<?> clazz = Class.forName("reflection.User");
Method method1 = clazz.getDeclaredMethod("method", Integer.class);
System.out.println("method1 = " + method1);
System.out.println("===================================");
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("declaredMethod = " + declaredMethod);
}
5.3. 获取Constructor类方法
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
:通过指定形参列表类型获取指定构造方法,可以获取所有修饰符修饰的构造方法public Constructor<?>[] getDeclaredConstructors()
:获取类中所有的构造方法,可以获取所有修饰符修饰的构造方法
// 通过Class.forName获取Class类
Class<?> clazz = Class.forName("reflection.User");
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(Integer.class);
System.out.println("declaredConstructor = " + declaredConstructor);
System.out.println("=================================");
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor<?> declaredConstructor1 : declaredConstructors) {
System.out.println("declaredConstructor1 = " + declaredConstructor1);
}
5.4. Class中其他方法
public String getName()
:获取当前类的名称public String getSimpleName()
:获取当前类简单名称public String getTypeName()
:获取类型名称public native int getModifiers()
:获取修饰符,返回int类型,值为Modifier
类中的16进制属性public InputStream getResourceAsStream(String name)
:获取类路径下的(resources目录)资源数据,会将数据存储到内存,多次读取数据是相同的public T newInstance()
:返回当前类的实例对象