- 直接已知的子类:
-
SecureClassLoader
ClassLoader
是一个抽象类。给定一个类的二进制名称,类加载器应尝试定位或生成构成该类定义的数据。一个典型的策略是将名称转换为文件名,然后从文件系统中读取该名称的“类文件”。
每个Class
对象都包含一个指向定义它的ClassLoader
的引用
。
数组类的Class
对象不是由类加载器创建的,而是根据Java运行时的需要自动创建。数组类的类加载器,如Class.getClassLoader()
返回的那样,与其元素类型的类加载器相同;如果元素类型是原始类型,则数组类没有类加载器。
应用程序通过实现ClassLoader
的子类来扩展Java虚拟机动态加载类的方式。
类加载器通常可被安全管理器用于指示安全域。
除了加载类,类加载器还负责定位资源。资源是一些数据(例如“.class
”文件、配置数据或图像),其使用抽象的“/”分隔路径名进行标识。资源通常与应用程序或库一起打包,以便应用程序或库中的代码可以定位它们。在某些情况下,资源被包含在内,以便其他库可以定位它们。
ClassLoader
类使用委托模型来搜索类和资源。每个ClassLoader
实例都有一个关联的父类加载器。当请求查找类或资源时,ClassLoader
实例通常会在尝试自己查找类或资源之前将类或资源的查找委托给其父类加载器。
支持并发加载类的类加载器称为并行能力类加载器,并且需要在其类初始化时通过调用ClassLoader.registerAsParallelCapable
方法进行注册。请注意,ClassLoader
类默认注册为具有并行能力。但是,如果它们具有并行能力,则其子类仍然需要注册自己。在不严格遵循层次结构的委托模型的环境中,类加载器需要具有并行能力,否则类加载可能会导致死锁,因为加载器锁在类加载过程中一直被持有(参见loadClass
方法)。
运行时内置类加载器
Java运行时具有以下内置类加载器:-
引导类加载器。它是虚拟机的内置类加载器,通常表示为
null
,并且没有父类加载器。 -
平台类加载器。平台类加载器负责加载平台类。平台类包括Java SE平台API、它们的实现类和由平台类加载器或其祖先定义的JDK特定运行时类。平台类加载器可以用作
ClassLoader
实例的父类加载器。为了允许升级/覆盖定义为平台类加载器的模块,并且升级的模块读取定义为平台类加载器以外的类加载器和其祖先的模块,那么平台类加载器可能必须委托给其他类加载器,例如应用程序类加载器。换句话说,定义为平台类加载器以外的类加载器和其祖先的命名模块中的类可能对平台类加载器可见。
-
系统类加载器。它也称为应用程序类加载器,与平台类加载器不同。系统类加载器通常用于在应用程序类路径、模块路径和JDK特定工具上定义类。平台类加载器是系统类加载器的父类或祖先,因此系统类加载器可以通过委托给其父类来加载平台类。
通常,Java虚拟机以与平台相关的方式从本地文件系统加载类。但是,某些类可能不是来自文件;它们可能来自其他来源,例如网络,或者它们可以由应用程序构造。方法defineClass
将字节数组转换为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) { // 从连接中加载类数据 . . } }
二进制名称
作为ClassLoader
方法中的String
参数提供的任何类名必须是由Java语言规范定义的二进制名称。
有效类名的示例包括:
"java.lang.String" "javax.swing.JSpinner$DefaultEditor" "java.security.KeyStore$Builder$FileBuilder$1" "java.net.URLClassLoader$3$1"
作为ClassLoader
方法中的String
参数提供的任何包名必须是空字符串(表示未命名包)或由Java语言规范定义的完全限定名称。
- 参见Java语言规范:
-
6.7 完全限定名称
13.1 二进制形式
- 自:
- 1.0
- 另请参见:
-
Constructor Summary
ModifierConstructorDescriptionprotected
使用方法getSystemClassLoader()
返回的ClassLoader
作为父类加载器创建一个新的类加载器。protected
ClassLoader
(ClassLoader parent) 使用指定的父类加载器进行委托创建一个新的类加载器。protected
ClassLoader
(String name, ClassLoader parent) 使用指定名称和指定父类加载器进行委托创建一个新的类加载器。 -
Method Summary
Modifier and TypeMethodDescriptionvoid
将此类加载器的默认断言状态设置为false
,并丢弃与该类加载器关联的任何包默认值或类断言状态设置。protected final Class
<?> defineClass
(byte[] b, int off, int len) 已弃用。protected final Class
<?> defineClass
(String name, byte[] b, int off, int len) 将字节数组转换为Class
类的实例。protected final Class
<?> defineClass
(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) 将字节数组转换为带有给定ProtectionDomain
的Class
类的实例。protected final Class
<?> defineClass
(String name, ByteBuffer b, ProtectionDomain protectionDomain) protected Package
definePackage
(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) 在此ClassLoader
中按名称定义一个包。protected Class
<?> 查找具有指定二进制名称的类。protected Class
<?> 在此类加载器定义的模块中查找具有给定二进制名称的类。protected String
findLibrary
(String libname) 返回本机库的绝对路径名。protected final Class
<?> findLoadedClass
(String name) protected URL
findResource
(String name) 查找具有给定名称的资源。protected URL
findResource
(String moduleName, String name) 返回在此类加载器定义的模块中资源的URL。protected Enumeration
<URL> findResources
(String name) 返回表示具有给定名称的所有资源的URL
对象的枚举。protected final Class
<?> findSystemClass
(String name) 查找具有指定二进制名称的类,如果需要则加载它。protected Object
getClassLoadingLock
(String className) 返回用于类加载操作的锁对象。final Package
getDefinedPackage
(String name) 返回由此类加载器定义的具有给定名称的Package
。final Package[]
返回由此类加载器定义的所有Package
。getName()
返回此类加载器的名称,如果此类加载器未命名,则返回null
。protected Package
getPackage
(String name) 已弃用。如果多个类加载器相互委托并定义具有相同包名称的类,并且其中一个加载器依赖于getPackage
的查找行为从父加载器返回Package
,则在程序的其余部分中暴露的Package
的属性可能不如预期。protected Package[]
返回由此类加载器及其祖先定义的所有Package
。final ClassLoader
返回用于委派的父类加载器。static ClassLoader
返回平台类加载器。getResource
(String name) 查找具有给定名称的资源。getResourceAsStream
(String name) 返回用于读取指定资源的输入流。getResources
(String name) 查找具有给定名称的所有资源。static ClassLoader
返回系统类加载器。static URL
getSystemResource
(String name) 从用于加载类的搜索路径中查找指定名称的资源。static InputStream
以读取方式打开用于加载类的搜索路径中指定名称的资源。static Enumeration
<URL> getSystemResources
(String name) 从用于加载类的搜索路径中查找指定名称的所有资源。final Module
返回此类加载器的未命名Module
。final boolean
Class
<?> 使用指定的二进制名称加载类。protected Class
<?> 使用指定的二进制名称加载类。protected static boolean
将调用者注册为并行可用。protected final void
resolveClass
(Class<?> c) 链接指定的类。返回一个流,其元素是具有给定名称的所有资源的URL。void
setClassAssertionStatus
(String className, boolean enabled) 设置此类加载器中指定顶级类的所需断言状态,以及其中包含的任何嵌套类。void
setDefaultAssertionStatus
(boolean enabled) 设置此类加载器的默认断言状态。void
setPackageAssertionStatus
(String packageName, boolean enabled) 设置指定包的默认断言状态。protected final void
setSigners
(Class<?> c, Object[] signers) 设置类的签名者。
-
Constructor Details
-
ClassLoader
创建指定名称的新类加载器,并使用指定的父类加载器进行委派。- API 注意:
-
如果父类加载器指定为
null
(用于引导类加载器),则不能保证所有平台类都可见。 - 参数:
-
name
- 类加载器名称;如果未命名,则为null
-
parent
- 父类加载器 - 抛出:
-
IllegalArgumentException
- 如果给定名称为空 -
SecurityException
- 如果存在安全管理器且其SecurityManager.checkCreateClassLoader()
方法不允许创建新的类加载器 - 自:
- 9
-
ClassLoader
使用指定的父类加载器创建新的类加载器。如果存在安全管理器,将调用其
checkCreateClassLoader
方法。这可能导致安全异常。- API 注意:
-
如果父类加载器指定为
null
(用于引导类加载器),则不能保证所有平台类都可见。 - 参数:
-
parent
- 父类加载器 - 抛出:
-
SecurityException
- 如果存在安全管理器且其checkCreateClassLoader
方法不允许创建新的类加载器 - 自:
- 1.2
-
ClassLoader
protected ClassLoader()使用方法getSystemClassLoader()
返回的ClassLoader
作为父类加载器创建新的类加载器。如果存在安全管理器,将调用其
checkCreateClassLoader
方法。这可能导致安全异常。- 抛出:
-
SecurityException
- 如果存在安全管理器且其checkCreateClassLoader
方法不允许创建新的类加载器
-
-
Method Details
-
getName
返回此类加载器的名称,如果此类加载器未命名则返回null
。- API 注意:
- 为了兼容性,此方法不是最终方法。如果重写此方法,则必须返回实例化此类加载器时指定的相同名称。
- 返回:
-
此类加载器的名称;如果此类加载器未命名则返回
null
。 - 自:
- 9
-
loadClass
使用指定的二进制名称加载类。此方法按照loadClass(String, boolean)
方法的方式搜索类。Java虚拟机调用此方法来解析类引用。调用此方法等效于调用loadClass(name, false)
。- 参数:
-
name
- 类的二进制名称 - 返回:
-
结果
Class
对象 - 抛出:
-
ClassNotFoundException
- 如果未找到类
-
loadClass
使用指定的二进制名称加载类。此方法的默认实现按以下顺序搜索类:-
调用
findLoadedClass(String)
检查类是否已加载。 -
在父类加载器上调用
loadClass
方法。如果父类加载器为null
,则使用虚拟机内置的类加载器。 -
调用
findClass(String)
方法查找类。
如果通过上述步骤找到类,并且
resolve
标志为true,则此方法将在结果Class
对象上调用resolveClass(Class)
方法。ClassLoader
的子类鼓励重写findClass(String)
,而不是此方法。除非重写,否则此方法在整个类加载过程中同步于
getClassLoadingLock
方法的结果。- 参数:
-
name
- 类的二进制名称 -
resolve
- 如果为true
,则解析类 - 返回:
-
结果
Class
对象 - 抛出:
-
ClassNotFoundException
- 如果找不到类
-
-
getClassLoadingLock
返回用于类加载操作的锁对象。- API 注意:
- 此方法允许并行可用的类加载器实现更细粒度的锁定方案,以便多个线程可以并发加载类而不会发生死锁。对于不支持并行的类加载器,类加载器对象在整个类加载操作期间都会同步。非层次委派的类加载器应该注册为并行可用以防止死锁。
- 实现要求:
-
如果此
ClassLoader
对象已注册为并行可用,则此方法返回与指定类名关联的专用对象。否则,此方法返回此ClassLoader
对象。 - 参数:
-
className
- 要加载的类的名称 - 返回:
- 类加载操作的锁
- 抛出:
-
NullPointerException
- 如果已注册为并行可用且className
为null
- 自:
- 1.7
- 参见:
-
findClass
- 实现要求:
-
默认实现会抛出
ClassNotFoundException
。 - 参数:
-
name
- 类的二进制名称 - 返回:
-
结果
Class
对象 - 抛出:
-
ClassNotFoundException
- 如果找不到类 - 自:
- 1.2
-
findClass
在此类加载器定义的模块中查找具有给定二进制名称的类。支持从模块加载的类加载器实现应该重写此方法。- API 注意:
-
如果找不到类,则此方法返回
null
而不是抛出ClassNotFoundException
。 - 实现要求:
-
默认实现尝试通过调用
findClass(String)
来查找类,当moduleName
为null
时。否则返回null
。 - 参数:
-
moduleName
- 模块名称;或者为null
以在此类加载器的未命名模块中查找类 -
name
- 类的二进制名称 - 返回:
-
结果
Class
对象,如果找不到类则返回null
。 - 自:
- 9
-
defineClass
@Deprecated(since="1.1") protected final Class<?> defineClass(byte[] b, int off, int len) throws ClassFormatError Deprecated.Replaced bydefineClass(String, byte[], int, int)
- 参数:
-
b
- 构成类数据的字节。位置off
到off+len-1
的字节应符合由Java虚拟机规范定义的有效类文件格式。 -
off
- 类数据在b
中的起始偏移量 -
len
- 类数据的长度 - 返回:
-
从指定类数据创建的
Class
对象 - 抛出:
-
ClassFormatError
- 如果数据不包含有效类 -
IndexOutOfBoundsException
- 如果off
或len
为负,或者off+len
大于b.length
-
SecurityException
- 如果尝试将此类添加到包含由不同证书集签名的类的包中,或者尝试在以"java.
"开头的完全限定名称的包中定义类。 - 参见:
-
defineClass
protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError 将字节数组转换为Class
类的实例。在使用Class
之前,必须对其进行解析。此方法为新定义的类分配一个默认的
ProtectionDomain
。当调用Policy.getPolicy().getPermissions(new CodeSource(null, null))
时,ProtectionDomain
实际上被授予与返回的相同的权限集。默认的保护域是在第一次调用defineClass
时创建的,并在后续调用中重复使用。要为类分配特定的
ProtectionDomain
,请使用接受ProtectionDomain
作为其参数之一的defineClass
方法。此方法在此类加载器中定义一个与
Class
的包对应的包(如果此类加载器中尚未定义此类包)。定义的包的名称源自由字节数组b
指定的类的二进制名称。定义的包的其他属性如Package
中指定的那样。- 参数:
-
name
- 类的预期二进制名称,如果不知道则为null
-
b
- 构成类数据的字节。位置off
到off+len-1
的字节应符合由Java虚拟机规范定义的有效类文件格式。 -
off
- 类数据在b
中的起始偏移量 -
len
- 类数据的长度 - 返回:
-
从指定类数据创建的
Class
对象。 - 抛出:
-
ClassFormatError
- 如果数据不包含有效类 -
IndexOutOfBoundsException
- 如果off
或len
为负,或者off+len
大于b.length
-
SecurityException
- 如果尝试将此类添加到包含由不同证书集签名的类的包中(未签名的类),或者如果name
以"java.
"开头。 - 自版本:
- 1.1
- 参见:
-
defineClass
protected final Class<?> defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) throws ClassFormatError 将字节数组转换为带有给定ProtectionDomain
的Class
类的实例。如果给定的
ProtectionDomain
为null
,则将根据defineClass(String, byte[], int, int)
文档为类分配默认的保护域。在使用类之前,必须对其进行解析。在包中定义的第一个类确定该包中所有后续定义的类必须包含的确切证书集。类的证书集从类的
ProtectionDomain
中的CodeSource
中获取。添加到该包中的任何类必须包含相同的证书集,否则将抛出SecurityException
。请注意,如果name
为null
,则不执行此检查。您应始终传递您正在定义的类的二进制名称以及字节。这可以确保您正在定义的类确实是您认为的类。如果指定的
name
以"java.
"开头,则只能由平台类加载器或其祖先定义;否则将抛出SecurityException
。如果name
不为null
,则它必须等于由字节数组b
指定的类的二进制名称,否则将抛出NoClassDefFoundError
。此方法在此类加载器中定义一个与
Class
的包对应的包(如果此类加载器中尚未定义此类包)。定义的包的名称源自由字节数组b
指定的类的二进制名称。定义的包的其他属性如Package
中指定的那样。- 参数:
-
name
- 类的预期二进制名称,如果不知道则为null
-
b
- 构成类数据的字节。位置off
到off+len-1
的字节应符合由Java虚拟机规范定义的有效类文件格式。 -
off
- 类数据在b
中的起始偏移量 -
len
- 类数据的长度 -
protectionDomain
- 类的ProtectionDomain
- 返回:
-
从数据创建的
Class
对象和ProtectionDomain
。 - 抛出:
-
ClassFormatError
- 如果数据不包含有效类 -
NoClassDefFoundError
- 如果name
不为null
且不等于由b
指定的二进制名称 -
IndexOutOfBoundsException
- 如果off
或len
为负,或者off+len
大于b.length
-
SecurityException
- 如果尝试将此类添加到包含由不同证书集签名的类的包中,或者如果name
以"java.
"开头且此类加载器不是平台类加载器或其祖先。
-
defineClass
protected final Class<?> defineClass(String name, ByteBuffer b, ProtectionDomain protectionDomain) throws ClassFormatError 将ByteBuffer
转换为带有给定ProtectionDomain
的Class
类的实例。如果给定的ProtectionDomain
为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
- 类的预期二进制名称,如果未知则为null
-
b
- 组成类数据的字节。从位置b.position()
到b.position() + b.limit() -1
的字节应符合由Java虚拟机规范定义的有效类文件格式。 -
protectionDomain
- 类的ProtectionDomain
,或null
。 - 返回:
-
从数据创建的
Class
对象,以及ProtectionDomain
。 - 抛出:
-
ClassFormatError
- 如果数据不包含有效类。 -
NoClassDefFoundError
- 如果name
不是null
且不等于由b
指定的类的二进制名称 -
SecurityException
- 如果尝试将此类添加到包含由不同证书集签名的类的软件包中,或者如果name
以"java.
"开头。 - 自版本:
- 1.5
- 参见:
-
resolveClass
链接指定的类。这个(名字有点误导的)方法可以被类加载器用来链接一个类。如果类c
已经被链接,那么这个方法只是简单地返回。否则,根据Java语言规范中“执行”章节的描述来链接类。- 参数:
-
c
- 要链接的类 - 抛出:
-
NullPointerException
- 如果c
为null
。 - 参见:
-
findSystemClass
查找具有指定二进制名称的类,必要时加载它。此方法通过系统类加载器(参见
getSystemClassLoader()
)加载类。返回的Class
对象可能与多个ClassLoader
相关联。通常不需要子类化ClassLoader
调用此方法,因为大多数类加载器只需要覆盖findClass(String)
。- 参数:
-
name
- 类的二进制名称 - 返回:
-
指定
name
的Class
对象 - 抛出:
-
ClassNotFoundException
- 如果找不到类 - 参见:
-
findLoadedClass
如果此加载器已被Java虚拟机记录为具有该二进制名称的类的启动加载器,则返回该类。否则返回null
。- 参数:
-
name
- 类的二进制名称 - 返回:
-
Class
对象,如果类尚未加载则返回null
- 自版本:
- 1.1
-
setSigners
设置类的签名者。在定义类之后应调用此方法。- 参数:
-
c
-Class
对象 -
signers
- 类的签名者 - 自版本:
- 1.1
-
findResource
返回到此类加载器定义的模块中的资源的URL。支持从模块加载的类加载器实现应覆盖此方法。- API注释:
-
此方法是
Class.getResource
、Class.getResourceAsStream
和Module.getResourceAsStream
方法的基础。它不受Module.getResourceAsStream
指定的封装规则的约束。 - 实现要求:
-
默认实现尝试通过调用
findResource(String)
来查找资源,当moduleName
为null
时。否则返回null
。 - 参数:
-
moduleName
- 模块名称;或null
以在此类加载器的未命名模块中查找资源 -
name
- 资源名称 - 返回:
-
资源的URL;如果找不到资源、无法构造URL以定位资源、安全管理器拒绝访问资源或没有为类加载器定义给定名称的模块,则返回
null
。 - 抛出:
-
IOException
- 如果发生I/O错误 - 自版本:
- 9
- 参见:
-
getResource
查找具有给定名称的资源。资源是类代码可以访问的一些数据(图像、音频、文本等),与代码位置无关的方式。资源的名称是一个以'
/
'分隔的路径名,用于标识资源。命名模块中的资源受
Module.getResourceAsStream
指定的封装规则约束。此外,除了资源名称以".class
"结尾的特殊情况外,此方法仅在包被无条件打开
时才在命名模块的包中查找资源(即使调用此方法的调用者与资源所在的模块相同)。- API注释:
-
当为同一类加载器定义了多个模块,并且多个模块包含具有给定名称的资源时,搜索模块的顺序未指定,可能非常不可预测。在覆盖此方法时,建议实现确保任何委托与
getResources(String)
方法一致。 - 实现要求:
-
默认实现首先搜索资源的父类加载器;如果父类加载器为
null
,则搜索内置于虚拟机中的类加载器的路径。如果未找到,则此方法将调用findResource(String)
来查找资源。 - 参数:
-
name
- 资源名称 - 返回:
-
用于读取资源的
URL
对象;如果找不到资源、无法构造URL
以定位资源、资源位于未无条件打开的包中或安全管理器拒绝访问资源,则返回null
。 - 抛出:
-
NullPointerException
- 如果name
为null
- 自版本:
- 1.1
-
getResources
查找具有给定名称的所有资源。资源是类代码可以访问的一些数据(图像、音频、文本等),与代码位置无关的方式。资源的名称是一个
/
分隔的路径名,用于标识资源。命名模块中的资源受
Module.getResourceAsStream
指定的封装规则约束。此外,除了资源名称以".class
"结尾的特殊情况外,此方法仅在包被无条件打开
时才在命名模块的包中查找资源(即使调用此方法的调用者与资源所在的模块相同)。- API注释:
-
当为同一类加载器定义了多个模块,并且多个模块包含具有相同名称的资源时,其顺序未指定且可能非常不可预测。在覆盖此方法时,建议实现确保任何委托与
getResource(String)
方法一致。这应确保枚举的nextElement
方法返回的第一个元素与getResource(String)
方法返回的资源相同。 - 实现要求:
-
默认实现将首先搜索父类加载器以查找资源;如果父类为
null
,则搜索内置于虚拟机中的类加载器的路径。然后调用findResources(String)
来查找此类加载器中具有该名称的资源。它返回一个枚举,其元素是通过搜索父类加载器找到的URL,然后是通过findResources
找到的元素。 - 参数:
-
name
- 资源名称 - 返回:
-
一个包含资源的
URL
对象的枚举。如果找不到资源,则枚举将为空。无法构造URL
的资源,位于未无条件打开的包中,或者由安全管理器拒绝访问的资源不会在枚举中返回。 - 抛出:
-
IOException
- 如果发生I/O错误 -
NullPointerException
- 如果name
为null
- 自:
- 1.2
-
resources
返回一个流,其元素是具有给定名称的所有资源的URL。资源是一些数据(图像、音频、文本等),可以通过类代码访问,而不依赖于代码的位置。资源的名称是一个用
/
分隔的路径名称,用于标识资源。在评估返回的流时将定位资源。如果评估导致
IOException
,则将在UncheckedIOException
中包装I/O异常,然后抛出。命名模块中的资源受
Module.getResourceAsStream
指定的封装规则约束。此外,除非资源的名称以".class
"结尾,否则此方法仅在命名模块的包中找到资源,当包无条件打开
时(即使调用此方法的调用者与资源位于同一模块中)。- API注释:
-
在覆盖此方法时,建议实现确保任何委托与
getResource(String)
方法一致。这应确保流返回的第一个元素与getResource(String)
方法返回的资源相同。 - 实现要求:
-
默认实现调用
getResources
来查找具有给定名称的所有资源,并返回一个包含枚举元素的流作为源。 - 参数:
-
name
- 资源名称 - 返回:
-
一个资源
URL
对象的流。如果找不到资源,则流将为空。无法构造URL
的资源,位于未无条件打开的包中,或者由安全管理器拒绝访问的资源将不在流中。 - 抛出:
-
NullPointerException
- 如果name
为null
- 自:
- 9
-
findResource
查找具有给定名称的资源。类加载器实现应该覆盖此方法。对于命名模块中的资源,该方法必须实现
Module
getResourceAsStream
方法中指定的封装规则。此外,除非资源的名称以".class
"结尾,否则不应在命名模块的包中找到非".class
"资源,除非该包无条件打开
。- 实现要求:
-
默认实现返回
null
。 - 参数:
-
name
- 资源名称 - 返回:
-
用于读取资源的
URL
对象;如果找不到资源、无法构造用于定位资源的URL
、资源位于未无条件打开的包中或者由安全管理器拒绝访问资源,则返回null
。 - 自:
- 1.2
-
findResources
返回表示具有给定名称的所有资源的URL
对象的枚举。类加载器实现应该覆盖此方法。对于命名模块中的资源,该方法必须实现
Module
getResourceAsStream
方法中指定的封装规则。此外,除非资源的名称以".class
"结尾,否则不应在命名模块的包中找到非".class
"资源,除非该包无条件打开
。- 实现要求:
- 默认实现返回一个不包含元素的枚举。
- 参数:
-
name
- 资源名称 - 返回:
-
用于资源的
URL
对象的枚举。如果找不到资源,则枚举将为空。无法构造URL
的资源,位于未无条件打开的包中,或者由安全管理器拒绝访问的资源不会在枚举中返回。 - 抛出:
-
IOException
- 如果发生I/O错误 - 自:
- 1.2
-
registerAsParallelCapable
protected static boolean registerAsParallelCapable()将调用者注册为并行能力。仅当满足以下所有条件时,注册才成功:- 未创建调用者的任何实例
- 调用者的所有超类(除了Object类)都已注册为并行能力
请注意,一旦将类加载器注册为并行能力,就无法将其改回。
在调用此方法的上下文中,如果调用者不是
ClassLoader
的子类或者堆栈上没有调用者帧(例如,直接从JNI附加的线程中调用),则会抛出IllegalCallerException
。- 返回:
-
如果调用者成功注册为并行能力,则返回
true
;否则返回false
。 - 抛出:
-
IllegalCallerException
- 如果调用者不是ClassLoader
的子类 - 自:
- 1.7
- 参见:
-
isRegisteredAsParallelCapable
public final boolean isRegisteredAsParallelCapable()- 返回:
-
如果此类加载器是并行能力的,则返回
true
;否则返回false
。 - 自:
- 9
- 参见:
-
getSystemResource
从用于加载类的搜索路径中查找指定名称的资源。此方法通过系统类加载器(请参见getSystemClassLoader()
)定位资源。命名模块中的资源受
Module.getResourceAsStream
指定的封装规则约束。此外,除非资源的名称以".class
"结尾,否则此方法仅在命名模块的包中找到资源,当包无条件打开
时。- 参数:
-
name
- 资源名称 - 返回:
-
资源的
URL
;如果找不到资源、无法构造用于定位资源的URL、资源位于未无条件打开的包中或者由安全管理器拒绝访问资源,则返回null
。 - 自:
- 1.1
-
getSystemResources
从用于加载类的搜索路径中查找指定名称的所有资源。找到的资源将作为Enumeration
的URL
对象返回。搜索顺序在
getSystemResource(String)
的文档中描述。命名模块中的资源受
Module.getResourceAsStream
指定的封装规则约束。此外,除非资源的名称以".class
"结尾,否则此方法仅在命名模块的包中找到资源,当包无条件打开
时。- 参数:
-
name
- 资源名称 - 返回:
-
为资源返回一个
URL
对象的枚举。如果找不到资源,则枚举将为空。无法构造URL
的资源,位于未无条件打开的包中的资源,或者由安全管理器拒绝访问的资源,不会在枚举中返回。 - 抛出:
-
IOException
- 如果发生 I/O 错误 - 自版本:
- 1.2
-
getResourceAsStream
返回用于读取指定资源的输入流。搜索顺序在
getResource(String)
的文档中有描述。命名模块中的资源受到由
Module.getResourceAsStream
指定的封装规则的约束。此外,除了资源名称以 ".class
" 结尾的特殊情况外,此方法仅在命名模块的包中找到资源时才会找到资源,当且仅当包是无条件opened
时。- 参数:
-
name
- 资源名称 - 返回:
-
用于读取资源的输入流;如果找不到资源,资源位于未无条件打开的包中,或者由安全管理器拒绝访问资源,则返回
null
。 - 抛出:
-
NullPointerException
- 如果name
为null
- 自版本:
- 1.1
-
getSystemResourceAsStream
从用于加载类的搜索路径中打开指定名称的资源进行读取。此方法通过系统类加载器定位资源(请参见getSystemClassLoader()
)。命名模块中的资源受到由
Module.getResourceAsStream
指定的封装规则的约束。此外,除了资源名称以 ".class
" 结尾的特殊情况外,此方法仅在命名模块的包中找到资源时才会找到资源,当且仅当包是无条件opened
时。- 参数:
-
name
- 资源名称 - 返回:
-
用于读取资源的输入流;如果找不到资源,资源位于未无条件打开的包中,或者由安全管理器拒绝访问资源,则返回
null
。 - 自版本:
- 1.1
-
getParent
返回用于委托的父类加载器。一些实现可能使用null
来表示引导类加载器。如果这个类加载器的父类是引导类加载器,则在这些实现中此方法将返回null
。- 返回:
-
父
ClassLoader
- 抛出:
-
SecurityException
- 如果存在安全管理器,并且调用者的类加载器不为null
,并且不是此类加载器的祖先,并且调用者没有RuntimePermission
("getClassLoader")
- 自版本:
- 1.2
-
getUnnamedModule
返回此类加载器的未命名Module
。- 返回:
- 此类加载器的未命名 Module
- 自版本:
- 9
- 参见:
-
getPlatformClassLoader
返回平台类加载器。所有 平台类 对平台类加载器可见。- 实现注意:
-
内置平台类加载器的名称为
"platform"
。 - 返回:
-
平台
ClassLoader
。 - 抛出:
-
SecurityException
- 如果存在安全管理器,并且调用者的类加载器不为null
,并且调用者的类加载器不同于平台类加载器或者不是平台类加载器的祖先,并且调用者没有RuntimePermission
("getClassLoader")
- 自版本:
- 9
-
getSystemClassLoader
返回系统类加载器。这是新ClassLoader
实例的默认委托父级,并且通常是用于启动应用程序的类加载器。此方法首先在运行时的启动序列中的早期阶段调用,此时它会创建系统类加载器。这个类加载器将是主应用程序线程的上下文类加载器(例如,调用主类的
main
方法的线程)。默认系统类加载器是此类的实现相关实例。
如果系统属性 "
java.system.class.loader
" 在首次调用此方法时被定义,则该属性的值将被视为将作为系统类加载器返回的类的名称。使用默认系统类加载器加载该类,并且必须定义一个接受类型为ClassLoader
的单个参数的公共构造函数,该构造函数用作委托父级。然后使用默认系统类加载器作为参数使用此构造函数创建一个实例。生成的类加载器被定义为系统类加载器。在构造过程中,类加载器应该非常小心避免调用getSystemClassLoader()
。如果检测到系统类加载器的循环初始化,则会抛出IllegalStateException
。- 实现注意:
-
要覆盖系统类加载器的系统属性直到 VM 几乎完全初始化。在启动期间执行此方法的代码应该注意在系统完全初始化之前不要缓存返回值。
内置系统类加载器的名称为
"app"
。在 VM 的早期初始化期间读取系统属性 "java.class.path
" 以确定类路径。"java.class.path
" 属性的空值根据初始模块(包含主类的模块)是命名的还是未命名的而有不同的解释:如果是命名的,则内置系统类加载器将没有类路径,并将使用应用程序模块路径搜索类和资源;否则,如果是未命名的,则将类路径设置为当前工作目录。类路径上的 JAR 文件可能包含一个
Class-Path
清单属性,用于指定要包含在类路径中的依赖 JAR 文件。Class-Path
条目必须满足某些有效性条件(有关详细信息,请参见 JAR 文件规范)。无效的Class-Path
条目将被忽略。出于调试目的,如果将jdk.net.URLClassPath.showIgnoredClassPathEntries
系统属性设置为true
,则忽略的条目可以打印到控制台。 - 返回:
-
系统
ClassLoader
- 抛出:
-
SecurityException
- 如果存在安全管理器,并且调用者的类加载器不为null
,并且不是系统类加载器或者不是系统类加载器的祖先,并且调用者没有RuntimePermission
("getClassLoader")
-
IllegalStateException
- 如果在构造由 "java.system.class.loader
" 属性指定的类加载器的过程中递归调用此方法。 -
Error
- 如果定义了系统属性 "java.system.class.loader
" 但无法加载命名类,提供程序类未定义所需的构造函数,或者在调用该构造函数时抛出异常。错误的根本原因可以通过Throwable.getCause()
方法检索。
-
definePackage
protected Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) 在此ClassLoader
中按 名称 定义一个包。包名称 必须在类加载器内是唯一的,并且一旦创建就不能重新定义或更改。
如果类加载器希望定义具有特定属性的包,例如版本信息的包,则类加载器应在调用
defineClass
之前调用此definePackage
方法。否则,defineClass
方法将在此类加载器中定义一个与新定义类的包相对应的包;此定义包的属性由Package
指定。- API 注释:
-
希望为JAR中的类定义包的类加载器通常使用JAR清单中的规范和实现标题、版本和供应商。如果在JAR的清单中将包指定为sealed,则JAR文件的
URL
通常用作sealBase
。如果由此类加载器定义的包'p'
的类是从多个JAR加载的,则Package
对象可能包含不同的信息,具体取决于首先定义包'p'
的类以及首先读取哪个JAR的清单以明确定义包'p'
。强烈建议类加载器不要调用此方法来显式定义在命名模块中的包;相反,当定义类时将自动定义包。如果希望显式定义
Package
,应确保所有命名模块中的包都使用Package
指定的属性进行定义。否则,命名模块中的一些Package
对象可能例如使用不同的seal base进行封装。 - 参数:
-
name
- 包名称 -
specTitle
- 规范标题 -
specVersion
- 规范版本 -
specVendor
- 规范供应商 -
implTitle
- 实现标题 -
implVersion
- 实现版本 -
implVendor
- 实现供应商 -
sealBase
- 如果不为null
,则该包将与给定代码源的URL
对象相关联。否则,该包未封装。 - 返回:
-
新定义的
Package
对象 - 抛出:
-
NullPointerException
- 如果name
为null
。 -
IllegalArgumentException
- 如果给定name
的包已由此类加载器定义 - 参见 Java虚拟机规范:
-
5.3 创建和加载
- 自版本:
- 1.2
- 另请参阅:
-
getDefinedPackage
返回由此类加载器定义的给定名称的Package
。- 参数:
-
name
- 包名称 - 返回:
-
由此类加载器定义的给定名称的
Package
,如果未找到则返回null
- 抛出:
-
NullPointerException
- 如果name
为null
。 - 参见 Java虚拟机规范:
-
5.3 创建和加载
- 自版本:
- 9
-
getDefinedPackages
返回由此类加载器定义的所有Package
。返回的数组中不包含相同名称的重复Package
。- API 注释:
-
为了与现有的
getPackages()
方法保持一致,此方法返回数组而不是Set
或Stream
。 - 返回:
-
由此类加载器定义的
Package
对象数组;如果此类加载器未定义任何包,则返回长度为零的数组。 - 参见 Java虚拟机规范:
-
5.3 创建和加载
- 自版本:
- 9
-
getPackage
Deprecated.If multiple class loaders delegate to each other and define classes with the same package name, and one such loader relies on the lookup behavior ofgetPackage
to return aPackage
from a parent loader, then the properties exposed by thePackage
may not be as expected in the rest of the program. For example, thePackage
will only expose annotations from thepackage-info.class
file defined by the parent loader, even if annotations exist in apackage-info.class
file defined by a child loader. A more robust approach is to use thegetDefinedPackage(java.lang.String)
method which returns aPackage
for the specified class loader.在此类加载器及其祖先中按名称查找包。如果此类加载器定义了给定名称的
Package
,则返回该Package
。否则,递归搜索此类加载器的祖先(逐级父级)以查找给定名称的Package
。- API 注释:
-
平台类加载器
可能委托给应用程序类加载器,但应用程序类加载器不是其祖先。在平台类加载器上调用此方法时,将不会找到定义为应用程序类加载器的包。 - 参数:
-
name
- 包名称 - 返回:
-
由此类加载器或其祖先定义的给定名称的
Package
,如果未找到则返回null
。 - 抛出:
-
NullPointerException
- 如果name
为null
。 - 自版本:
- 1.2
- 另请参阅:
-
getPackages
返回由此类加载器及其祖先定义的所有Package
。返回的数组可能包含同一包名称的多个Package
对象,每个由类加载器层次结构中的不同类加载器定义。- API 注释:
-
平台类加载器
可能委托给应用程序类加载器。换句话说,定义为应用程序类加载器的模块中的包可能对平台类加载器可见。另一方面,应用程序类加载器不是其祖先,因此在平台类加载器上调用此方法时,将不会返回定义为应用程序类加载器的任何包。 - 返回:
-
由此类加载器及其祖先定义的
Package
对象数组 - 自版本:
- 1.2
- 另请参阅:
-
findLibrary
返回本机库的绝对路径名。VM调用此方法来定位属于使用此类加载器加载的类的本机库。如果此方法返回null
,VM将沿着指定为"java.library.path
"属性的路径搜索库。- 参数:
-
libname
- 库名称 - 返回:
- 本机库的绝对路径
- 自版本:
- 1.2
- 另请参阅:
-
setDefaultAssertionStatus
public void setDefaultAssertionStatus(boolean enabled) 设置此类加载器的默认断言状态。此设置确定此类加载器加载的类以及将来初始化的类是否默认启用或禁用断言。此设置可以通过调用setPackageAssertionStatus(String, boolean)
或setClassAssertionStatus(String, boolean)
来覆盖每个包或每个类的基础设置。- 参数:
-
enabled
- 如果此类加载器加载的类将来将默认启用断言,则为true
,如果将默认禁用断言,则为false
。 - 自版本:
- 1.4
-
setPackageAssertionStatus
设置指定包的默认断言状态。包默认断言状态确定将来初始化的属于指定包或其任何"子包"的类的断言状态。包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
值表示"当前"的未命名包(请参阅The Java Language Specification的第7.4.2节)。 -
enabled
- 如果此类加载器加载的属于指定包或其任何子包的类将来将默认启用断言,则为true
,如果将默认禁用断言,则为false
。 - 自版本:
- 1.4
-
setClassAssertionStatus
设置此类加载器中指定顶级类及其包含的任何嵌套类的所需断言状态。此设置优先于类加载器的默认断言状态,以及任何适用的包默认。如果指定类已经被初始化,则此方法不起作用。(一旦类被初始化,其断言状态就无法更改。)如果指定类不是顶级类,则此调用对任何类的实际断言状态都没有影响。
- 参数:
-
className
- 要设置断言状态的顶级类的完全限定类名。 -
enabled
- 如果在初始化时(如果有的话)要启用命名类的断言,则为true
,如果要禁用类的断言,则为false
。 - 自版本:
- 1.4
-
clearAssertionStatus
public void clearAssertionStatus()将此类加载器的默认断言状态设置为false
,并丢弃与类加载器关联的任何包默认值或类断言状态设置。提供此方法是为了使类加载器可以忽略任何命令行或持久的断言状态设置,并“以干净的状态启动”。- 自版本:
- 1.4
-
defineClass(String, byte[], int, int)
替代