一、类的加载
类的加载一共分为三步:
1、加载
就是将类加载进内存,并同时创建一个Class对象(就是描述一个 .class 文件的对象)
而且任何类被使用前都会先创建一个 Class对象
2、连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
3、初始化
见前面的初始化笔记。
初始化的时机:
创建类的实例
访问类的静态变量,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类
二、类的加载器
类加载器
负责将.class文件加载到内在中,并为之生成对应的Class对象。
类加载器的组成
1、Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如: System,String等。在JDK中JRE的lib目录下rt.jar文件中
2、Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录
3、Sysetm ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,
以及classpath环境变量所指定的jar包和类路径
(一般此加载器加载的就是我们所写的文件)
三、反射
概念:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
就是通过一定的方法(如:通过 .class文件的文件名)来指向一个 .class文件,在获得一个用来
描述这个 .class文件的 Class 对象,
之后通过该Class对象来获取文件中的 构造方法、成员变量、成员方法, (既可以批量获取,
也可以单个获取,既可以获取public 类型的,也可获取private类型的, 甚至可以通过暴力访问的方法
来访问 private的成员。)
通过获取到的构造方法,可以得到一个Object型的该类对象,(Constructer)
通过获取到的成员 和 该类对象,可以操作.class文件中的成员了。(Field, Method)
获取Class对象:
1、Object的 getClass 方法。
2、数据类型的静态属性 class (引用类型、基本类型)。
3、Class类中的静态方法。
static Class<?> forName(String className)
static Class<?> forName(String name, boolean initialize, ClassLoader loader)
获取构造方法:
获取构造方法
getConstructors(Class<?>... parameterTypes)
getDeclaredConstructors()
创建对象
newInstance()
con.newInstance(“zhangsan", 20);
获取成员变量:
获取所有成员
getFields,
getDeclaredFields
获取单个成员
getField,
getDeclaredField
修改成员的值
set(Object obj,Object value)
将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
获取成员方法:
获取所有方法
getMethods
getDeclaredMethods
获取单个方法
getMethod
getDeclaredMethod
暴力访问
method.setAccessible(true);
四、动态代理
动态代理: 在程序运行过程中产生的这个对象
而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,
所以,动态代理其实就是通过反射来生成一个代理
就是说,我们需要对一个我们已有的对象的方法添加一些新的功能,而这些功能对每个对象、
每个方法都是相同的, 那么我们就可以使用动态代理来获得一个该对象的动态代理对象,
使用该对象再调用的方法,就是被动态代理过后的方法。
在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,
通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。
我们有更强大的代理cglib
Proxy类中的方法创建动态代理类对象
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
最终会调用InvocationHandler的方法
InvocationHandler
Object invoke(Object proxy,Method method,Object[] args)