首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java ClassLoader 與 Package 機制深度解析

     編輯:Java 相關知識

為深入了解 Java ClassLoader 機制,先做實驗:

package java.lang;
public class Test {
    public static void main(String[] args) {
        char[] c = "1234567890".toCharArray();
        String s = new String(0, 10, c);
    }
}

String 類有一個 package 權限的構造函數 String(int offset, int length, char[] array),按預設訪問權限,Test 屬於 java.lang 包,理論上可訪問。編譯通過,但運行拋出 SecurityException: Prohibited package name: java.lang。要弄清原因,必須搞懂 ClassLoader 機制。

ClassLoader 機制

Java ClassLoader 動態加載 class,對一個 class 只加載一次。JVM 使用的 ClassLoader 共 4 種,優先級由高到低:

  1. 啟動類加載器
  2. 標準擴展類加載器
  3. 類路徑加載器
  4. 網絡類加載器

採用「雙親委派模型」:若網絡類加載器被請求加載 java.lang.Integer,會先將請求發送給上一級類路徑加載器;若上一級返回已加載,則網絡類加載器不再加載;否則才自行加載。類似地,類路徑加載器收到請求後也會先委派給標準擴展類加載器,以此類推。啟動類加載器優先級最高,若它按自己方式找到 java.lang.Integer,下層 ClassLoader 都無法再加載該類,即使你自己寫了一個 java.lang.Integer 也無法取代核心庫的類,因根本無法被下層加載器加載。

Package 權限的真相

Java 語言規定:同一包中無修飾符默為 package 權限,包內類可訪問。但這不夠準確。確切說,只有由同一個 ClassLoader 加載的類才擁有上述 package 權限。例如啟動類加載器加載了 java.lang.String,類路徑加載器加載了我們寫的 java.lang.Test,它們無法互相訪問對方的 package 權限方法。這就阻止了惡意代碼訪問核心類的 package 權限方法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved