理解Java中的统一化对象
我试图理解在Java中如何将引用存储到理解Java中的统一化对象,java,class,object,jvm,Java,Class,Object,Jvm,我试图理解在Java中如何将引用存储到Object[]中。因此,我使用ASM库生成了一个类,如下所示: public static Class<?> getKlass(){ String className = "TestClass"; ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); classWriter.visit(V1_8, ACC_PUBLIC, classNa
Object[]
中。因此,我使用ASM
库生成了一个类
,如下所示:
public static Class<?> getKlass(){
String className = "TestClass";
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classWriter.visit(V1_8, ACC_PUBLIC, className, null, getInternalName(Object.class), null);
MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC + ACC_STATIC, "m", "()[Ljava/lang/Object;",null, null);
//ARRAY_SIZE
mv.visitInsn(ICONST_1);
mv.visitTypeInsn(ANEWARRAY, getInternalName(Object.class));
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitTypeInsn(NEW, getInternalName(Object.class));
mv.visitInsn(AASTORE); // <--- Here is the problem
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
return new ByteArrayClassLoader().defineClass(classWriter.toByteArray());
}
添加构造函数调用按预期工作
mv.visitTypeInsn(NEW, getInternalName(Object.class));
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, getInternalName(Object.class), "<init>", "()V", false);
mv.visitInsn(AASTORE);
mv.visitTypeInsn(新的,getInternalName(Object.class));
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL,getInternalName(Object.class),“”,“()V”,false);
visitInsn号(AASTORE);
现在它工作得很好。但其行为尚不清楚。我希望未初始化和初始化的对象具有相同的类型。如中所述,我们没有特殊的未初始化类型。所以我希望JVM允许加载带有未初始化引用的类
我遗漏了什么?有一个未初始化的类型,但它只存在于验证程序resp中。堆栈内映射表条目应该有助于验证程序。由于严格要求包含NEW
指令的方法必须通过invokespecial
调用构造函数,并且必须在使用对象之前调用构造函数,因此无需在常规类型系统中对其建模。一旦验证程序确保每个方法都正确初始化了对象,您就不会在不适当的位置遇到未初始化的对象
委员会:
uninitialized此
是在调用超类构造函数之前,构造函数中的此
引用的类型uninitialized(Offset)
是在调用构造函数之前由NEW
创建的实例的类型。“偏移量
”是指方法字节码中的新
指令的指令偏移量。这允许跟踪多个未初始化的实例,例如在执行new Foo(new Bar(new Baz())
或甚至new Foo(new Foo(new Foo())
时。如中所述,将未初始化实例绑定到创建NEW
指令会对代码结构施加一些限制,例如,不能合并不同NEW
指令的未初始化类型,即使它们在调用构造函数后具有相同的引用类型
mv.visitTypeInsn(NEW, getInternalName(Object.class));
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, getInternalName(Object.class), "<init>", "()V", false);
mv.visitInsn(AASTORE);
Verification type hierarchy:
top
____________/\____________
/ \
/ \
oneWord twoWord
/ | \ / \
/ | \ / \
int float reference long double
/ \
/ \_____________
/ \
/ \
uninitialized +------------------+
/ \ | Java reference |
/ \ | type hierarchy |
uninitializedThis uninitialized(Offset) +------------------+
|
|
null