JVM学习笔记 番外2 - 类加载器的一些梳理

JVM学习笔记 番外2 - 类加载器的一些梳理

类加载器的双亲:

  • 类加载器中的父子关系,并不是 java 对象中的继承关系;

双亲委派机制的意义:

  • 避免类的重复加载,当父加载器已经加载过了就不会再加载了,保证每个类对象只有一份;
  • 保证 java 核心 API 的安全性,避免被篡改
    • 若网络中有一个类 java.lang.Object 被要求加载进内存,子类加载器会委派给双亲加载器直至到 bootstrap classloader,根类加载器会查询内存中已加载的类对象,发现已加载过就不会再次加载而是直接返回已经存在的类,防止核心 api 库被篡改;

用户不能以 java.、javax.、sun.* 为开头的包名 定义类,避免混淆;

package java.cat;

public class MyObject {
}
package new_package.jvm.test;
import java.cat.MyObject;
public class ClassLoaderTest {
    public static void main(String[] args) {
        ClassLoader classLoader2 = MyObject.class.getClassLoader();
        System.out.println(classLoader2);
    }

}
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.cat
	at java.lang.ClassLoader.preDefineClass(ClassLoader.java:662)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:761)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at new_package.jvm.bv1o7411v7DS.ClassLoaderTest.main(ClassLoaderTest.java:19)

ClassLoader 类中的四个关键方法:

  • loadClass
    • 双亲委派的实现
    • 轻易不要覆盖此方法
  • findClass
    • 自定义类加载器,主要实现的方法
  • defineClass
    • 根据 byte[] 转换成 jvm 能识别的 Class 对象
  • resolveClass
    • 类加载之后的连接阶段

在这里插入图片描述
图片来源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章