类加载与反射
类加载
class类
java.lang.Class类封装一个对象和接口运行时的状态。
当加载类时Class类型的对象将自动创建,通过Class对象就可以访问JVM中类的所有信息。
Class类没有公共构造方法,其对象是JVM在加载类时通过类加载器中的defineClass()方法自动构造的,因此不能显式地构造一个Class对象。
可以获取所有构造方法,方法,变量,内部类,外部类,对应类的修饰符,并且判断类型。
获取Class对象有三种方法:
- Class.forName(“所需类的全限定类名”)
- 调用某个类的class方法 Float.class
- 调用某个对象的getClass()方法 a.getClass()
类加载步骤
当程序主动使用某个类时,如果该类还未被加载到内存中,系统将通过加载,连接和初始化三个步骤对类进行初始化。
类加载器
类加载器负责将磁盘或者网络上的.class文件加载到内存中,并为之生成对应的java.lang.Class对象
类加载器负责加载所有的类,JVM启动时,会形成由三个类加载器组成的初始类加载器层次结构:
- Bootstrap ClassLoader:根类加载器,负责加载Java的核心类库
- Extension ClassLoader:扩展类加载器,负责加载JRE的扩展目录中的jar包
- System ClassLoader:系统类加载器,负责在JVM启动时加载来自Java命令的-classpath选项,java.class.path系统属性,或CLASSPATH环境变量所指定的jar包和类路径
- 用户也可以自定义加载器
1
2
3
4
5
6
7根类加载器
|
扩展类加载器
|
系统类加载器
|
用户类加载器
tips:类加载机制:全盘负责,父类委托,缓存机制
ClassLoader类
java.lang.ClassLoader是一个抽象类,通过继承ClassLoader类来实现自定义的用户类加载器,重写方法
实现自定义的类加载器可以通过重写ClassLoader类的loadClass()或findClass()方法来实现。推荐重写findClass()避免覆盖默认类加载器的父类委托,缓冲机制两种策略
反射
java中有许多对象在运行时都会出现两种类型:编译时类型和运行时类型,
某些情况下程序会在运行时接收到外部传入的一个对象,该对象的编译时类型和运行时类型不同,
但程序需要调用该对象运行时类型的方法,在无法预知该对象属于哪些类的情况下,必须通过反射来发现该对象和类的真实信息。
反射机制允许程序在运行时借助Reflection API取得任何类的内部信息,并能直接操作对象的内部属性和方法。反射被视为动态语言的关键。
java反射机制主要提供了以下功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时获取任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
- 生成动态代理
Reflection API提供了Constructor,Field和Method类,这三个类定义在java.lang.reflect包中,分别用于描述类的构造方法,属性和方法
java.lang.reflect包下的Executable抽象类,该对象代表可执行的类成员。
Executable抽象类派生了Constructor和Method两个子类。
Executable抽象类提供了大量方法来获取参数,修饰符或注解等信息
Executable方法列表
方法 | 功能描述 |
---|---|
Parameter[] getParameters() | 获取所有形参,返回一个Parameter[]数组 |
int getParameterCount() | 获取形参个数 |
abstract int getModifiers | 获取修饰符,返回的整数是修饰符所对应的常量 |
boolean isVarArgs() | 判断是否包含数量可变的形参 |
Constructor类用于表示类的构造方法,通过调用Class对象的getConstructor()方法可以获取当前类的构造方法的集合
Constructor类方法列表
方法 | 功能描述 |
---|---|
String getName() | 返回构造方法的名称 |
Class[] getParameterTypes() | 返回当前构造方法的参数类型 |
int getModifiers() | 返回修饰符的整型标识,返回的整数是修饰符public,protected,private,final,static,abstract等关键字所对应的常量,需要使用Modifier工具类的方法解码后才能获得真实的修饰符 |
Method类用于封装方法的信息,调用Class对象的getMethods()方法或getMethod()可以获取当前类的所有方法或指定方法
Method类常用方法
方法 | 功能描述 |
---|---|
String getName() | 返回方法的名称 |
Class[] getParameterTypes() | 返回当前方法的参数类型 |
int getModifiers() | 返回修饰符的整型标识 |
Class getReturnType() | 返回当前方法的返回类型 |
Field类用于封装属性的信息,调用Class对象的getFields()或getField()方法可以获得当前类的所有属性或指定属性。
Field类常用方法
方法 | 功能描述 |
---|---|
String getName() | 返回属性的名称 |
int getModifiers() | 返回修饰符的整型标识 |
getXxx(Object obj) | 获取属性的值,此处的Xxx对应java中基本类型;如果属性是引用类型,则直接使用get(Object obj) |
setXxx(Object obj,Xxx val) | 设置属性值;set(Object obj,Object val) |
Class [] getType() | 返回当前属性的类型 |
Parameter类,每个Parameter对象代表方法的一个参数。Parameter类中提供了许多方法来获取参数信息。
Parameter类常用方法
方法 | 功能描述 |
---|---|
int getModifiers() | 获取参数的修饰符 |
String getName() | 获取参数的形参名 |
Type getParameterizedType() | 获取带泛型的形参类型 |
Class<?>getType() | 获取形参类型 |
boolean isVarArgs() | 判断该参数是否是可变参数 |
boolean isNamePresent() | 判断.class文件中是否包含方法的形参名信息 |