一、Class类
1、万事万物皆对象,所以我们创建的每一个类也都是对象,即类本身是java.lang.Class类的实例对象,但是这些对象都不需要new出来,因为java.lang.Class类的构造方法是私有的
2、任何一个类都是Class类的实例对象,这个实例对象有三种表示方式
1).通过类名获取 类名.class
2).通过对象获取 对象名.getClass()
3).通过全类名获取 Class.forName(全类名)
Class类的常用方法:
反射基本介绍:
1. Class: 是一个类; 一个描述类的类.
Class类:代表一个类
Field类:代表类的成员变量(类的属性)
Method类:代表类的方法
Constructor类:代表类的构造方法
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
2. 关于 Method:
2.1 如何获取 Method:
1). getDeclaredMethods: 得到 Method 的数组.
2). getDeclaredMethod(String methondName, Class ... parameterTypes)
2.2 如何调用 Method
1). 如果方法时 private 修饰的, 需要先调用 Method 的setAccessible(true), 使其变为可访问
2). method.invoke(obj, Object ... args);
3. 关于 Field:
3.1 如何获取 Field: getField(String fieldName)
3.2 如何获取 Field 的值:
1). setAccessible(true)
2). field.get(Object obj)
3.3 如何设置 Field 的值:
field.set(Obejct obj, Object val)
4. 了解 Constructor 和 Annotation
5. 反射和泛型.
5.1 getGenericSuperClass: 获取带泛型参数的父类, 返回值为: BaseDao<Employee, String>
5.2 Type 的子接口: ParameterizedType
5.3 可以调用 ParameterizedType 的 Type[] getActualTypeArguments() 获取泛型参数的数组。
二、动态加载类
1、编译时加载类是静态加载类,
new 创建对象是静态加载类,在编译时刻就需要加载所有可用使用到的类,如果有一个用不了,那么整个文件都无法通过编译
2、运行时加载类是动态加载类
Class c = Class.forName("类的全名"),不仅表示了类的类型,还表示了动态加载类,编译不会报错,在运行时才会加载,
使用接口标准能更方便动态加载类的实现。功能性的类尽量使用动态加载,而不用静态加载。
三、类的加载
类装载器是用来把类(class)装载进 JVM 的。JVM 规范定义了两种类型的类装载器:
启动类装载器(bootstrap)和用户自定义装载器(user-defined class loader)。
JVM在运行时会产生3个类加载器组成的初始化加载器层次结构 ,如下图所示:
1、当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化
1)、加载:就是指将class文件读入内存,并为之创建一个Class对象,任何类被使用时系统都会建立一个Class对象
2)、连接:
验证:确保被加载类的正确性
准备:负责为类的静态成员分配内存,并设置默认初始化值
解析:将类中的符号引用替换为直接引用
3)、初始化:
局部变量保存在栈区:必须手动初始化
new 的对象保存在堆区:虚拟机会进行默认初始化,基本数据类型初始化值为0,引用类型初始化值为null
2、类加载的时机(只加载一次)
① 创建类的实例的时候;② 访问类的静态变量的时候
③ 调用类的静态方法的时候;④ 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
⑤ 初始化某个类的子类的时候;⑥ 直接使用java.exe命令来运行某个主类
3、类加载器
负责将.class文件加载到内存中,并为之生成对应的Class对象
虽然我们在开发过程中不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。
4、类加载器的组成:
①Bootstrap ClassLoader 根类加载器,也被称为引导类加载器,负责Java核心类的加载,比如System类,在JDK中JRE的lib目录下rt.jar文件中的类
②Extension ClassLoader 扩展类加载器负责JRE的扩展目录中jar包的加载,在JDK中JRE的lib目录下ext目录
③System ClassLoader 系统类加载器负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径,主要是我们开发者自己写的类。
java 反射代码讲解github地址:https://github.com/hxy021102/java-reflex