为什么 Unsafe.allocateInstance(Class.class) 失败了?
Why Unsafe.allocateInstance(Class.class) failed?
我现在使用的是不安全的。当我运行下面的代码:
unsafe.allocateInstance(Class.class)
发生了
Exception in thread "main" java.lang.IllegalAccessException: java.lang.Class
既然Class
是一个非抽象的class,为什么这么特别呢?有什么方法可以构造一个 'empty' Class
像 allocateInstance
?
因为HotSpot JVM内部有一个明确的检查来确保java.lang.Class
不能通过JNI、Unsafe等实例化。见instanceKlass.cpp:
void InstanceKlass::check_valid_for_instantiation(bool throwError, TRAPS) {
if (is_interface() || is_abstract()) {
ResourceMark rm(THREAD);
THROW_MSG(throwError ? vmSymbols::java_lang_InstantiationError()
: vmSymbols::java_lang_InstantiationException(), external_name());
}
if (this == SystemDictionary::Class_klass()) {
ResourceMark rm(THREAD);
THROW_MSG(throwError ? vmSymbols::java_lang_IllegalAccessError()
: vmSymbols::java_lang_IllegalAccessException(), external_name());
}
}
这样的实例无论如何都是无效的,所以它没有意义。
我现在使用的是不安全的。当我运行下面的代码:
unsafe.allocateInstance(Class.class)
发生了
Exception in thread "main" java.lang.IllegalAccessException: java.lang.Class
既然Class
是一个非抽象的class,为什么这么特别呢?有什么方法可以构造一个 'empty' Class
像 allocateInstance
?
因为HotSpot JVM内部有一个明确的检查来确保java.lang.Class
不能通过JNI、Unsafe等实例化。见instanceKlass.cpp:
void InstanceKlass::check_valid_for_instantiation(bool throwError, TRAPS) {
if (is_interface() || is_abstract()) {
ResourceMark rm(THREAD);
THROW_MSG(throwError ? vmSymbols::java_lang_InstantiationError()
: vmSymbols::java_lang_InstantiationException(), external_name());
}
if (this == SystemDictionary::Class_klass()) {
ResourceMark rm(THREAD);
THROW_MSG(throwError ? vmSymbols::java_lang_IllegalAccessError()
: vmSymbols::java_lang_IllegalAccessException(), external_name());
}
}
这样的实例无论如何都是无效的,所以它没有意义。