|
JavaTM 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 Platform Standard Ed. 6 |
|||||||||
上一个类 下一个类 | 框架 无框架 | |||||||||
摘要: 嵌套 | 字段 | 构造方法 | 方法 | 详细信息: 字段 | 构造方法 | 方法 |
版权所有 2007 Sun Microsystems, Inc. 保留所有权利。 请遵守许可证条款。另请参阅文档重新分发政策。