1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.java 源码(带泛型)

【编译阶段】javac
✔ 类型检查(泛型安全)
✔ 类型擦除(类型参数 → 上界/Object)
✔ 插入必要的强制类型转换
✔ 生成桥方法(如需要)
✔ 在 class 文件中记录泛型签名(Signature)

.class 字节码
✔ 运行时类型:已擦除(无泛型参与执行)
✔ 元数据:包含泛型签名(仅供反射/工具读取)

【类加载】JVM 加载 class

在方法区(元空间)存储类结构信息

在堆中创建对应的 Class 对象(类的元信息入口)

【运行时】通过 Class 创建对象(new

反射是以Class对象为入口,访问JVM中保存的类结构信息(字段、方法、构造器、泛型等),并进行操作(调用/创建/修改)。

Class类只有私有构造函数,因此对应Class对象只能有JVM创建和加载。

Class类对象的获取

Field表示Class对象所表示的类的成员变量,通过它可以在运行时动态修改成员变量的属性值(包含private)。

Method表示Class对象所表示的类的成员方法,通过它可以动态调用对象的方法(包含private)。

获取class对象的方式的主要有三种:

  • 根据类名:类名.class
  • 根据对象:对象.getClass()
  • 根据全限定类名:Class.forName(全限定类名)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package org.example;

public class fansheDemo {
public static void main(String[] args) throws ClassNotFoundException {
//获取类
Class<Demo>[] classes=new Class[]{
Demo.class,
new Demo("小白",11).getClass(),
Class.forName("org.example.Demo")
};

for(Class c:classes){
System.out.println(c);
}
}
}
class Demo{
private String name;
private int age;
public Demo(String name,int age){
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
方法 说明
forname() 先加载类,再执行静态初始化
getClass() 获取Class对象的一个引用,返回表示该对象的实际类型的Class引用。
getName() 取全限定的类名(包括包名),即类的完整名字,内部类用$分隔
getSimpleName() 获取类名(不包括包名)
getCanonicalName() 返回语言规范名称,内部类用.分隔,匿名类返回null
isInterface() 判断Class对象是否表示一个接口
getInterfaces() 返回当前类直接实现的接口,不包括从父类继承的接口
getSuperclass() 返回Class对象,表示Class对象所引用的类所继承的直接基类。应用该方法可在运行时发现一个对象完整的继承结构
newInstance() 返回一个Object对象,是实现“虚拟构造器”的一种途径。使用该方法创建的类,必须带有无参的构造器

Constructor

Constructor类表示的是Class对象所表示的类的构造方法,利用它可以在运行时动态创建对象。