「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」
相关知识
反射相关的主要类
-
java.lang.Class:代表一个类, Class对象表示某个类加载后在堆中的对象
-
java.lang.reflect.Method:代表类的方法
-
java.lang.reflect.Field:代表类的成员变量
-
java.lang.reflect.Constructor:代表类的构造方法
注意:这些类在java.lang.reflection
反射机制的作用
1.在运行时判断任意一个对象所属的类
2.在运行时构造任意一个类的对象
3.在运行时得到任意一个类所具有的成员变量和方法
4.在运行时调用任意一个对象的成员变量和方法
5.生成动态代理
Class类基本介绍
- Class也是类,因此也继承Object类
- Class类对象不是new出来的,而是系统创建的
- 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
- 每个类的实例都会记得自己是由哪个Class实例所生成
- 通过Class可以完整地得到一个类的完整结构,通过一系列API
- Class对象是存放在堆的
- 类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据
java程序在计算机的三个阶段

有哪些类型拥有Class对象
1.外部类,成员内部类,静态内部类,局部内部类,匿名内部类
2.interface:接口
3.数组
4.enum:枚举
5.annotation:注解
6.基本数据类型
7.void
类加载
反射机制是java实现动态语言的关键,也就是通过反射实现类动态加载。
1.静态加载:编译时加载相关的类,如果没有则报错,依赖性太强
2.动态加载:运行时加载需要的类,如果运行时不用该类,则不报错,降低了依赖性
静态加载

动态加载

类加载时机
1.当创建对象时(new) //静态加载
2.当子类被加载时,父类也加载 //静态加载
3.调用类中的静态成员时 //静态加载
4.通过反射 //动态加载
类加载过程

类加载后内存布局情况

类加载过程详解:

加载阶段
JVM在该阶段的主要目的是将字节码从不同的数据源(可能是class 文件、也可能是jar包,甚至网络)转化为二进制字节流加载到内存中,并生成一个代表该类的java.lang.Class对象
连接阶段——验证

源代码:
SecurityManager sm = System.getSecurityManager();
public static SecurityManager getSecurityManager() {
return security;
}
连接阶段——准备


连接阶段——解析

初始化阶段
Initialization(初始化)
1.到初始化阶段,才真正开始执行类中定义的Java程序代码,此阶段是执行 ()方法的过程。
2.()方法是由编译器按语句在源文件中出现的顺序,依次自动收集类中的所有 静态变量的赋值动作和静态代码块中的语句,并进行合并。
3.虚拟机会保证一个类的()方法在多线程环境中被正确地加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的()方法,其他线程都需要阻塞等待,直到活动线程执行()方法完毕
同步机制
正因为有这个机制,才能保证某个类在内存中,只有一份Class对象
通过反射类获取类的结构信息
java.lang.Class类中的方法
- getName:获取全类名
- getSimpleName:获取简单类名
- getFields:获取所有public修饰的属性,包含本类以及父类的
- getDeclaredFields:获取本类中所有属性
- getMethods:获取所有public修饰的方法,包含本类以及父类的
- getDeclaredMethods:获取本类中所有方法
- getConstructors:获取所有public修饰的构造器,包含本类以及父类的
- getDeclaredConstructors:获取本类中所有构造器
- getPackage:以Package形式返回包信息
- getSuperClass:以Class形式返回父类信息
- getlnterfaces:以Class[]形式返回接口信息
- getAnnotations:以Annotation[]形式返回注解信息