|
JavaTM 2 Platform Standard Ed. 6 |
|||||||||
上一個類別 下一個類別 | 框架 無框架 | |||||||||
摘要: 巢狀 | 欄位 | 建構子 | 方法 | 詳細資訊: 欄位 | 建構子 | 方法 |
java.lang.Object java.lang.ClassLoader
public abstract class ClassLoader
類別載入器是負責載入類別的物件。ClassLoader 類別是一個抽象類別。如果給定類別的二進制名稱,那麼類別載入器會試圖尋找或產生構成類別定義的資料。一般策略是將名稱轉換為某個檔案名,然後從檔案系統讀取該名稱的“類別檔案”。
每個 Class
物件都包含一個對定義它的 ClassLoader 的參考
。
陣列類別的 Class 物件不是由類別載入器創建的,而是由 Java 運行時根據需要自動創建。陣列類別的類別載入器由 Class.getClassLoader()
返回,該載入器與其元素型別的類別載入器是相同的;如果該元素型別是基本型別,則該陣列類別沒有類別載入器。
應用程序需要實作 ClassLoader 的子類別,以擴展 Java 虛擬機器動態載入類別的方式。
類別載入器通常由安全管理器使用,用於指示安全域。
ClassLoader 類別使用委託模型來搜尋類別和資源。每個 ClassLoader 實例都有一個相關的父類別載入器。需要尋找類別或資源時,ClassLoader 實例會在試圖親自尋找類別或資源之前,將搜尋類別或資源的任務委託給其父類別載入器。虛擬機器的內置類別載入器(稱為 "bootstrap class loader")本身沒有父類別載入器,但是可以將它用作 ClassLoader 實例的父類別載入器。
通常情況下,Java 虛擬機器以與平臺有關的方式,從本地檔案系統中載入類別。例如,在 UNIX 系統中,虛擬機器從 CLASSPATH 環境變數定義的目錄中載入類別。
然而,有些類別可能並非源自一個檔案;它們可能源自其他來源(如網路),也可能是由應用程序建構的。defineClass
方法將一個 byte 陣列轉換為 Class 類別的實例。這種新定義的類別的實例可以使用 Class.newInstance
來創建。
類別載入器所創建物件的方法和建構子可以參考其他類別。為了確定參考的類別,Java 虛擬機器將調用最初創建該類別的類別載入器的 loadClass
方法。
例如,應用程序可以創建一個網路類別載入器,從伺服器中下載類別檔案。範例程式碼如下所示:
ClassLoader loader = new NetworkClassLoader(host, port); Object main = loader.loadClass("Main", true).newInstance(); . . .
網路類別載入器子類別必須定義方法 findClass
和 loadClassData,以實作從網路載入類別。下載組成該類別的位元組後,它應該使用方法 defineClass
來創建類別實例。範例實作如下:
class NetworkClassLoader extends ClassLoader { String host; int port; public Class findClass(String name) { byte[] b = loadClassData(name); return defineClass(name, b, 0, b.length); } private byte[] loadClassData(String name) { // load the class data from the connection . . . } }
按照《Java Language Specification》的定義,任何作為 String
型別參數傳遞給 ClassLoader 中方法的類別名稱都必須是一個二進制名稱。
有效類別名稱的範例包括:
"java.lang.String" "javax.swing.JSpinner$DefaultEditor" "java.security.KeyStore$Builder$FileBuilder$1" "java.net.URLClassLoader$3$1"
resolveClass(Class)
建構子摘要 | |
---|---|
protected |
ClassLoader()
使用方法 getSystemClassLoader() 返回的 ClassLoader 創建一個新的類別載入器,將該載入器作為父類別載入器。 |
protected |
ClassLoader(ClassLoader parent)
使用指定的、用於委託操作的父類別載入器創建新的類別載入器。 |
方法摘要 | |
---|---|
void |
clearAssertionStatus()
將此類別載入器的預設斷言狀態設置為 false,並放棄與此類別載入器關聯的所有預設包或類別斷言狀態設置。 |
protected Class<?> |
defineClass(byte[] b,
int off,
int len)
已過時。 由 defineClass(String, byte[], int, int) 取代 |
protected Class<?> |
defineClass(String name,
byte[] b,
int off,
int len)
將一個 byte 陣列轉換為 Class 類別的實例。 |
protected Class<?> |
defineClass(String name,
byte[] b,
int off,
int len,
ProtectionDomain protectionDomain)
使用可選的 ProtectionDomain 將一個 byte 陣列轉換為 Class 類別的實例。 |
protected Class<?> |
defineClass(String name,
ByteBuffer b,
ProtectionDomain protectionDomain)
使用可選的 ProtectionDomain 將 ByteBuffer 轉換為 Class 類別的實例。 |
protected Package |
definePackage(String name,
String specTitle,
String specVersion,
String specVendor,
String implTitle,
String implVersion,
String implVendor,
URL sealBase)
根據 name 在此 ClassLoader 中定義套件。 |
protected Class<?> |
findClass(String name)
使用指定的二進制名稱尋找類別。 |
protected String |
findLibrary(String libname)
返回本機資源庫的絕對路徑名。 |
protected Class<?> |
findLoadedClass(String name)
如果 Java 虛擬機器已將此載入器記錄為具有給定二進制名稱的某個類別的啟動載入器,則返回該二進制名稱的類別。 |
protected URL |
findResource(String name)
尋找具有給定名稱的資源。 |
protected Enumeration<URL> |
findResources(String name)
返回表示所有具有給定名稱的資源的 URL 物件的列舉。 |
protected Class<?> |
findSystemClass(String name)
尋找具有指定的二進制名稱的類別,必要時載入它。 |
protected Package |
getPackage(String name)
返回由此類別載入器或其任何祖先所定義的 Package。 |
protected Package[] |
getPackages()
返回此類別載入器及其祖先所定義的所有 Package。 |
ClassLoader |
getParent()
返回委託的父類別載入器。 |
URL |
getResource(String name)
尋找具有給定名稱的資源。 |
InputStream |
getResourceAsStream(String name)
返回讀取指定資源的輸入串流。 |
Enumeration<URL> |
getResources(String name)
尋找所有給定名稱的資源。 |
static ClassLoader |
getSystemClassLoader()
返回委託的系統類別載入器。 |
static URL |
getSystemResource(String name)
從用來載入類別的搜尋路徑中尋找具有指定名稱的資源。 |
static InputStream |
getSystemResourceAsStream(String name)
從用來載入類別的搜尋路徑打開具有指定名稱的資源,以讀取該資源。 |
static Enumeration<URL> |
getSystemResources(String name)
從用來載入類別的搜尋路徑中尋找所有具有指定名稱的資源。 |
Class<?> |
loadClass(String name)
使用指定的二進制名稱來載入類別。 |
protected Class<?> |
loadClass(String name,
boolean resolve)
使用指定的二進制名稱來載入類別。 |
protected void |
resolveClass(Class<?> c)
連接指定的類別。 |
void |
setClassAssertionStatus(String className,
boolean enabled)
設置在此類別載入器及其包含的巢狀類別中指定的最高層類別所需的斷言狀態。 |
void |
setDefaultAssertionStatus(boolean enabled)
設置此類別載入器的預設斷言狀態。 |
void |
setPackageAssertionStatus(String packageName,
boolean enabled)
為指定包設置預設斷言狀態。 |
protected void |
setSigners(Class<?> c,
Object[] signers)
設置類別的簽署者。 |
從類別 java.lang.Object 繼承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
建構子詳細資訊 |
---|
protected ClassLoader(ClassLoader parent)
如果存在安全管理器,則調用其 checkCreateClassLoader
方法。這可能導致安全性異常。
parent
- 父類別載入器
SecurityException
- 如果存在安全管理器並且其 checkCreateClassLoader 方法不允許創建新的類別載入器。protected ClassLoader()
getSystemClassLoader()
返回的 ClassLoader 創建一個新的類別載入器,將該載入器作為父類別載入器。
如果存在安全管理器,則調用其 checkCreateClassLoader
方法。這可能導致安全性異常。
SecurityException
- 如果存在安全管理器並且其 checkCreateClassLoader 方法不允許創建新的類別載入器。方法詳細資訊 |
---|
public Class<?> loadClass(String name) throws ClassNotFoundException
loadClass(String, boolean)
方法相同的方式搜尋類別。Java 虛擬機器調用它來分析類別參考。調用此方法等效於調用 loadClass(name, false)
。
name
- 類別的二進制名稱
ClassNotFoundException
- 如果沒有找到類別protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
調用 findLoadedClass(String)
來檢查是否已經載入類別。
在父類別載入器上調用 loadClass
方法。如果父類別載入器為 null,則使用虛擬機器的內置類別載入器。
調用 findClass(String)
方法尋找類別。
如果使用上述步驟找到類別,並且 resolve 標誌為真,則此方法將在得到的 Class 物件上調用 resolveClass(Class)
方法。
鼓勵用 ClassLoader 的子類別覆寫 findClass(String)
,而不是使用此方法。
name
- 類別的二進制名稱resolve
- 如果該參數為 true,則分析這個類別
ClassNotFoundException
- 如果無法找到類別protected Class<?> findClass(String name) throws ClassNotFoundException
loadClass
方法調用。預設實作拋出一個 ClassNotFoundException。
name
- 類別的二進制名稱
ClassNotFoundException
- 如果無法找到類別@Deprecated protected final Class<?> defineClass(byte[] b, int off, int len) throws ClassFormatError
defineClass(String, byte[], int, int)
取代
b
- 組成類別資料的位元組。off 與 off+len-1 之間的位元組應該具有《Java Virtual Machine Specification》定義的有效類別檔案的格式。off
- 類別資料的 b 中的起始偏移量len
- 類別資料的長度
ClassFormatError
- 如果資料不包含有效類別
IndexOutOfBoundsException
- 如果 off 或 len 為負,或者 off+len 大於 b.length。loadClass(String, boolean)
,
resolveClass(Class)
protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError
此方法將預設的 ProtectionDomain
分派給新定義的類別。調用 Policy.getPolicy().getPermissions(new CodeSource(null, null))
時,ProtectionDomain 被有效授予所返回的相同權限集。預設域在第一次調用 defineClass
時創建,並在後續調用時被重用。
要將特定的 ProtectionDomain 分派給類別,需要使用 defineClass
方法,該方法將 ProtectionDomain 用作其參數之一。
name
- 所需要的類別的二進制名稱,如果不知道此名稱,則該參數為 nullb
- 組成類別資料的位元組。off 與 off+len-1 之間的位元組應該具有《Java Virtual Machine Specification》定義的有效類別檔案的格式。off
- 類別資料的 b 中的起始偏移量len
- 類別資料的長度
ClassFormatError
- 如果資料不包含有效類別
IndexOutOfBoundsException
- 如果 off 或 len 為負,或者 off+len 大於 b.length。
SecurityException
- 如果試圖將此類別添加到包含由不同證書集簽章的類別(而不是此類別,此類別未簽章)的套件中,或者 name 以 "java." 開頭。loadClass(String, boolean)
,
resolveClass(Class)
,
CodeSource
,
SecureClassLoader
protected final Class<?> defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) throws ClassFormatError
defineClass(String, byte[], int, int)
的文檔中指定的類別。這個類別必須分析後才能使用。
套件中定義的第一個類別確定在該套件中定義的所有後續類別必須包含的證書的確切集合。從該類別的 ProtectionDomain 中的 CodeSource
可以獲得類別的證書集合。添加到該套件中的任何類別都必須包含相同的證書集合,否則拋出 SecurityException 異常。注意,如果 name 為 null,則不執行該檢查。應該始終傳入要定義的類別的二進制名稱以及位元組。這可確保定義該類別的正確性。
指定的 name 不能以 "java." 開頭,因為 "java.*" 套件中的全部類別都只能由引導類別載入器定義。如果 name 不是 null,則它必定等於由 byte 陣列 "b" 指定的類別的二進制名稱,否則將拋出 NoClassDefFoundError。
name
- 所需類別的二進制名稱,如果不知道此名稱,則該參數為 nullb
- 組成類別資料的位元組。從 off 到 off+len-1 的位元組應該具有由《Java Virtual Machine Specification》定義的有效類別檔案的格式。off
- 類別資料的 b 中的起始偏移量len
- 類別資料的長度protectionDomain
- 類別的 ProtectionDomain
ClassFormatError
- 如果資料不包含有效的類別
NoClassDefFoundError
- 如果 name 不等於 b 指定的類別的二進制名稱。
IndexOutOfBoundsException
- 如果 off 或者 len 為負,或者 off+len 大於 b.length。
SecurityException
- 如果試圖將此類別添加到某個包中,而這個包中包含由不同證書集合(而不是該類別)簽章的類別,或者 name 以 "java." 開頭。protected final Class<?> defineClass(String name, ByteBuffer b, ProtectionDomain protectionDomain) throws ClassFormatError
ByteBuffer
轉換為 Class 類別的實例。如果該域為 null,則將預設域分派給 defineClass(String, byte[], int, int)
的文檔中指定的類別。這個類別必須分析後才能使用。
有關包中定義的第一個類別(它確定了套件的證書集合)的規則,以及對類別名稱的限制,都與 defineClass(String, byte[], int, int, ProtectionDomain)
的文檔中指定的相同。
調用形式為 cl.defineClass(name, bBuffer, pd) 的此方法所產生的結果與以下語句產生的結果相同
...
byte[] temp = new byte[bBuffer.remaining
()];
bBuffer.get
(temp);
returncl.defineClass(name, temp, 0, temp.length, pd);
name
- 所需要的類別的二進制名稱,如果不知道此名稱,則該參數為 nullb
- 組成類別資料的位元組。從 b.position 到 b.position() + b.limit() -1 的位元組應該具有由《Java Virtual Machine Specification》定義的有效類別檔案的格式。protectionDomain
- 類別的 ProtectionDomain,或為 null。
ClassFormatError
- 如果資料不包含有效的類別。
NoClassDefFoundError
- 如果 name 不等於 b 指定的類別的二進制名稱。
SecurityException
- 如果試圖將此類別添加到某個包中,而這個包中包含由不同證書集合(而不是該類別)簽章的類別,或者 name 以 "java." 開頭。defineClass(String, byte[], int, int, ProtectionDomain)
protected final void resolveClass(Class<?> c)
c
- 要連接的類別
NullPointerException
- 如果 c 為 null。defineClass(String, byte[], int, int)
protected final Class<?> findSystemClass(String name) throws ClassNotFoundException
此方法通過系統類別載入器(參見 getSystemClassLoader()
)來載入該類別。返回的 Class 物件具有多個與之相關聯的 ClassLoader。ClassLoader 的子類別通常不必調用此方法,因為大多數類別載入器只需覆寫 findClass(String)
即可。
name
- 類別的二進制名稱
ClassNotFoundException
- 如果找不到類別ClassLoader(ClassLoader)
,
getParent()
protected final Class<?> findLoadedClass(String name)
name
- 類別的二進制名稱
protected final void setSigners(Class<?> c, Object[] signers)
c
- Class 物件signers
- 類別的簽署者public URL getResource(String name)
資源名稱是以 '/' 分隔的標識資源的路徑名稱。
此方法首先搜尋資源的父類別載入器;如果父類別載入器為 null,則搜尋的路徑就是虛擬機器的內置類別載入器的路徑。如果搜尋失敗,則此方法將調用 findResource(String)
來尋找資源。
name
- 資源名稱
public Enumeration<URL> getResources(String name) throws IOException
資源名稱是以 '/' 分隔的標識資源的路徑名稱。
getResource(String)
的文檔中描述了搜尋順序。
name
- 資源名稱
URL
物件的列舉。如果找不到資源,則該列舉將為空。類別載入器無權存取的資源不在此列舉中。
IOException
- 如果發生 I/O 錯誤findResources(String)
protected URL findResource(String name)
name
- 資源名稱
protected Enumeration<URL> findResources(String name) throws IOException
URL
物件的列舉。類別載入器實作應該覆寫此方法,以指定從何處載入資源。
name
- 資源名稱
URL
物件的列舉
IOException
- 如果發生 I/O 錯誤public static URL getSystemResource(String name)
getSystemClassLoader()
)來尋找資源。
name
- 資源名稱
URL
物件,如果找不到資源,則返回 nullpublic static Enumeration<URL> getSystemResources(String name) throws IOException
URL
物件的 Enumeration
返回。
getSystemResource(String)
的文檔中描述了搜尋順序。
name
- 資源名稱
URL
物件的列舉
IOException
- 如果發生 I/O 錯誤public InputStream getResourceAsStream(String name)
getResource(String)
的文檔中描述了搜尋順序。
name
- 資源名稱
public static InputStream getSystemResourceAsStream(String name)
getSystemClassLoader()
)來尋找資源。
name
- 資源名稱
public final ClassLoader getParent()
如果存在安全管理器,且調用者的類別載入器既不是 null,也不是此類別載入器的祖先,那麼此方法將使用 RuntimePermission("getClassLoader")
權限調用安全管理器的 checkPermission
方法,以檢驗是否允許存取該類別的父類別載入器。如果無此權限,則拋出 SecurityException 異常。
SecurityException
- 如果存在安全管理器,並且其 checkPermission 方法不允許存取此類別載入器的父類別載入器。public static ClassLoader getSystemClassLoader()
在運行時啟動序列的早期首先調用此方法,這時會創建系統類別載入器並將其設置為調用 Thread 的上下文類別載入器。
預設的系統類別載入器是此類別的一個與實作有關的實例。
如果在第一次調用此方法時定義系統屬性 "java.system.class.loader",那麼該屬性的值就是將作為系統類別載入器返回的那個類別的名稱。該類別是使用預設系統類別載入器進行載入的,它必須定義一個公共的建構子,此建構子帶有用作委託父類別載入器的 ClassLoader 型別的單個參數。然後可以使用將預設系統類別載入器用作參數的此建構子創建一個實例。得到的類別載入器被定義為系統類別載入器。
如果存在安全管理器,且調用者的類別載入器既不是 null,也不同於或不是系統類別載入器的祖先,那麼該方法將使用 RuntimePermission("getClassLoader")
權限調用安全管理器的 checkPermission
方法,以檢驗系統類別載入器的存取權。如果無此權限,則拋出 SecurityException 異常。
SecurityException
- 如果存在安全管理器,且其 checkPermission 方法不允許存取系統類別載入器。
IllegalStateException
- 如果在建構由 "java.system.class.loader" 屬性指定的類別載入器期間進行遞歸調用。
Error
- 如果定義了系統屬性 "java.system.class.loader",但是無法載入指定的類別,提供者類別沒有定義所需的建構子,或者在調用該建構子時拋出異常。可以通過 Throwable.getCause()
方法找出導致該錯誤的基本原因。protected Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) throws IllegalArgumentException
name
- 套件名specTitle
- 規範標題specVersion
- 規範版本specVendor
- 規範供應商implTitle
- 實作標題implVersion
- 實作版本implVendor
- 實作供應商sealBase
- 如果不為 null,那麼將此套件對於給定程式碼源 URL
物件是密封的。否則,不密封此套件。
IllegalArgumentException
- 如果包名與此類別載入器或其某個祖先中的現有套件的名稱重複protected Package getPackage(String name)
name
- 套件名
protected Package[] getPackages()
protected String findLibrary(String libname)
libname
- 資源庫名稱
System.loadLibrary(String)
,
System.mapLibraryName(String)
public void setDefaultAssertionStatus(boolean enabled)
setPackageAssertionStatus(String, boolean)
或 setClassAssertionStatus(String, boolean)
,在每個包或每個類別上覆寫此設置。
enabled
- 如果由此類別載入器載入的類別將預設為啟用斷言,則該參數為 true;如果預設為禁用斷言,則該參數為 false。public void setPackageAssertionStatus(String packageName, boolean enabled)
名為 p 的套件的子套件是所有名稱以 "p." 開頭的套件。例如,javax.swing.text 是 javax.swing 的子包,java.util 和 java.lang.reflect 是 java 的子套件。
如果預設情況下多個包可應用於一個給定類別,則預設與最特殊的套件相關的套件擁有高於其他套件的優先級。例如,如果 javax.lang 和 javax.lang.reflect 都具有與之相關的預設包,則將後者應用於 javax.lang.reflect 中的類別。
套件的優先級預設情況下高於類別載入器的預設斷言狀態,並且可以通過調用 setClassAssertionStatus(String, boolean)
在每個類別的基礎上進行覆寫。
packageName
- 要設置其預設包斷言狀態的套件名。null 值指示未命名的套件為「當前」狀態(Java Language Specification 的第 7.4.2 節)。enabled
- 如果由此類別載入器載入並屬於指定包或其子套件的類別在預設情況下啟用斷言,則該參數為 true;如果在預設情況下禁用斷言,則該參數為 false。public void setClassAssertionStatus(String className, boolean enabled)
如果指定類別不是最高層的類別,則此調用對任何類別的實際斷言都無效。
className
- 將要設置其斷言狀態的最高層類別的完全限定類別名。enabled
- 如果指定類別在初始化時啟用斷言,則該參數為true;如果該類別禁用斷言,則該參數為false。public void clearAssertionStatus()
|
JavaTM 2 Platform Standard Ed. 6 |
|||||||||
上一個類別 下一個類別 | 框架 無框架 | |||||||||
摘要: 巢狀 | 欄位 | 建構子 | 方法 | 詳細資訊: 欄位 | 建構子 | 方法 |
版權所有 2008 Sun Microsystems, Inc. 保留所有權利。請遵守GNU General Public License, version 2 only。