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
    • 類加載之後的連接階段

在這裏插入圖片描述
圖片來源

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