标签:null span extends bsp width 通过 步骤 code 多个
这是jvm那块的知识,复习一下,这其实是和反射有关系的。
指的是将类的class文件读入内存,并为之创建一个java.lang.Class对象(类是种定义,但在java里,万物都是对象,即类这种定义也是对象的一种),也就是说,当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象。
系统中所有的class类实际上也是实例,它们都是java.lang.Class的实例。
类的加载由加载器完成,类加载器通常由JVM提供,这些类加载器也是前面所有程序运行的基础。JVM提供的这些类加载器通常被称为系统加载器。除此之外,开发者可以通过继承ClassLoader基类来创建自己的类加载器。
类加载通常无需等到“首次使用”该类是才加载该类,Java虚拟机规范允许系统预先加载某类。
当类被加载之后,系统为之生成一个对应的Class对象,接着进入连接阶段。连接阶段负责把类的二进制数据合并到JRE中。
三阶段验证、准备、解析,看https://www.cnblogs.com/NoYone/p/8989916.html 连接阶段
初始化阶段的重要工作是执行类的初始化方法<clinit>,方法<clinit>是由编译器自动生成,主要是对静态Field进行初始化(赋值和静态代码块)。
JVM初始化一个类包含如下几个步骤:
由第二条可以推出,JVM最先初始化的总是java.lang.Object类。
注意:
public class 类的初始化测试 { public static void main(String[] args) throws ClassNotFoundException { // 取得系统类加载器,默认的 ClassLoader cl = ClassLoader.getSystemClassLoader(); // 下面语句仅仅加载Tester类 cl.loadClass("Test"); System.out.println("系统加载Tester类"); Syttem.out.printLn("----加载完成----"); // 下面语句才会初始化Tester类 Class.forName("Test"); } } public class Test { static { System.out.println("Test类的静态代码块"); } }
运行结果: JVM : -XX: TraceClassLoading
[Loaded DealReflect.类的初始化测试 from file:/E:/Intellij-Idea/fromXiaoXin/experiment/target/classes/] [Loaded Test from file:/E:/Intellij-Idea/fromXiaoXin/experiment/target/classes/] 系统加载Tester类
----加载完成----
Test类的静态代码块
可以看出loadClass只加载,Class.forName才会引出初始化。
类加载器负责将.class文件(可能在磁盘上,也可能是网络上)加载到内存中,并为之生成java.lang.Class对象。
注意:这里所说的父子关系不是继承上的父子关系,这里的父子关系是类加载器实例之间的关系(直接说运行顺序不完了。。) URLClassLoader可以从文件或者网络中加载类。例如:file: http:
JVM中4种类加载器层次
建议用第二种,因为能在编译阶段就能判断需要访问的Class对象是否存在。
获取到类对象后,程序就可以调用Class对象的方法来获取该对象和该类的真实信息了。
在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口可以生成JDK动态代理类或动态代理对象。
Proxy提供了用于创建动态代理类和动态代理对象的方法,它是所有动态代理类的父类。
执行代理对象的每个方法时都会被替换执行InvocationHandler对象的invoke方法。如何看生成的代理类里的代码(保存代理类过程在https://www.cnblogs.com/NoYone/p/8733868.html)
注意super.h.invoke,上面也说了,Proxy是父类,h就是传给Proxy的InvocationHandler,调用invoke方法。
Proxy类的两个方法:
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces):创建一个动态代理类对象的Class对象,该代理类将实现interfaces所指定的多个接口。第一个参数XXX.class.getClassLoader()
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h):直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的系列接口。
实际上,即是采用第一个方法获取了一个动态代理类之后,当程序需要通过该代理类来创建对象时一样需要传入一个InvocationHandler对象。也就是说,系统生成的每个代理类对象都有一个与之关联的InvocationHandler对象。即super.h.invoke(Object, Method, Object[])
小Demo看这里的就可以https://www.cnblogs.com/NoYone/p/8733868.html
标签:null span extends bsp width 通过 步骤 code 多个
原文地址:https://www.cnblogs.com/NoYone/p/10398011.html