标题说明了一切,这是代码:
private ClassLoader(Void unused, ClassLoader parent) {
this.parent = parent;
if (ParallelLoaders.isRegistered(this.getClass())) {
parallelLockMap = new ConcurrentHashMap<>();
package2certs = new ConcurrentHashMap<>();
domains =
Collections.synchronizedSet(new HashSet<ProtectionDomain>());
assertionLock = new Object();
} else {
// no finer-grained lock; lock on the classloader instance
parallelLockMap = null;
package2certs = new Hashtable<>();
domains = new HashSet<>();
assertionLock = this;
}
}
答案 0 :(得分:2)
在类加载器可以实例化之前,这看起来像是一个聪明的技巧来调用安全检查。
快速实验确认在任何初始化器之前调用静态方法:
public class InitializerTest {
{
System.out.println("Initializer block");
}
private InitializerTest(Void v) {
System.out.println("Constructor");
}
protected InitializerTest() {
this(staticMethod());
}
private static Void staticMethod() {
System.out.println("Static method");
return null;
}
}
哪个输出:
Static method
Initializer block
Constructor
显然,永远不允许实例化流氓ClassLoader
子类比实例化后失败更安全。例如。即使超类在其第一个初始化程序块中失败,该实例也在那里 - 也许在子类的finalize()
方法中可能有利用?