I'm trying to understand how storing a reference into Object[]
works in Java. So I generated a Class
with ASM
library as follows:
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());
}
When I run this code JVM signals with java.lang.VerifyError
that
Type uninitialized 6 (current frame, stack[3]) is not assignable to 'java/lang/Object'
Adding constructor invokation works as expected
mv.visitTypeInsn(NEW, getInternalName(Object.class));
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, getInternalName(Object.class), "<init>", "()V", false);
mv.visitInsn(AASTORE);
Now it works fine. But the behavior is not clear. I expected the uninitialized and initialized objects have the same type. As specified in JVMS we do not have a special uninitialized type. So I expected JVM allows to load the class with uninitialized reference.
What did I miss?