OptimisticReference0 is referred!主动引用2 – 创建子类会触发父类的初始化代码示例:
Parent is referred!Child is referred!主动引用3 – 访问一个类静态变量代码示例:
Child is referred!Child主动引用4 – 对类的静态变量进行赋值代码示例:
Child is referred!主动引用5 – 使用java.lang.reflect包提供的反射机制代码示例:
Child is referred!被动引用被动引用: 在类加载阶段,会执行加载、连接和初始化操作。
Parent is referred!Parent被动引用2 – 定义类的数组引用而不赋值,不会触发此类的初始化代码示例:
无输出被动引用3 – 访问类定义的常量,不会触发此类的初始化示例代码:
Child(四). 三种类加载器类加载器:类加载器负责加载程序中的类型(类和接口),并赋予唯一的名字予以标识。
ClassLoader通过loadClass()方法实现了双亲委托机制,用于类的动态加载。loadClass()本身是一个递归向上调用的过程。
查找当前类加载器的缓存中是否已经加载目标类。findLoadedClass()实际调用了底层的native方法findLoadedClass0()。
查找最顶端Bootstrap类加载器的是否已经加载目标类。同样,findBootstrapClassOrNull()实际调用了底层的native方法findBootstrapClass()。
ClassLoader是java.lang包下的抽象类,也是所有类加载器(除了Bootstrap)的基类,findClass()是ClassLoader对子类提供的加载目标类的抽象方法。
注意:Bootstrap ClassLoader并不属于JVM的层次,它不遵守ClassLoader的加载规则,Bootstrap classLoader并没有子类。
defineClass()是ClassLoader向子类提供的方法,它可以将.class文件的二进制数据转换为合法的java.lang.Class对象。(六). 类的动态加载类的几种加载方式
Step 1:定义待加载的目标类Parent.java和Children.java。Parent.java
Step 2:实现自定义类加载器CustomClassLoaderCustomClassLoader.java
Step 3:测试类加载器的加载过程CustomerClassLoaderTester.java
我们成功创建了Children对象,并通过反射调用了它的say()方法。然而查看控制台日志,可以发现类加载使用的仍然是AppClassLoader,CustomClassLoader并没有生效。查看CustomClassLoader的类加载目录:
类目录下有我们拷贝并编译的Parent和Chidren文件。分析原因:
由于项目空间中的Parent.java和Children.java,在拷贝后并没有移除。导致AppClassLoader优先在其Classpath下面找到并成功加载了目标类。(二). 测试场景二
我们成功通过自定义类加载器加载了目标类。创建了Children对象,并通过反射调用了它的say()方法。至此,我们自己的一个简单的类加载器就完成了!


| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |