I don't recall ever seeing any notion of reference variable types in Java bytecode. I know a bit about type erasure, but this term seems tightly linked to generics, whereas my question is about object reference variables in general. Do Java object reference variable types survive compilation ? Or do variable types merely serve the role of helping the compiler help the developer check that the code makes sense ? If reference variable types survive compilation, where do they appear in bytecode ?
EDIT: Allow me thank you here for all your valuable contributions. In order to narrow in a bit more on what I had in mind, I would like to add an example :
Object o = "foo";
In bytecode, will the variable o and its type (Object) be represented anywhere AND be read at runtime ?
Yes, bytecode is type-safe as well. First of all there is a byte code instruction called checkcast that is used every time you downcast:
Object obj = "abc";
String s = (String)obj;
is translated to:
aload_1
checkcast #3 // class java/lang/String
astore_2
Secondly invokevirtual and others expect an object of a given type. If you pass a wrong type, JVM will refuse loading such class. I don't think it's achievable in Java language, so I did a bit hacking. The following code:
Integer x = 1;
String s = "abc";
int len = s.length();
is translated to:
0: iconst_1
1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1
5: ldc #3 // String abc
7: astore_2
8: aload_2
9: invokevirtual #4 // Method java/lang/String.length:()I
12: istore_3
Notice instruction 8 that loads s local variable. Using hex editor I replaced aload_2 with aload_1, thus trying to call String.length() on an Integer object (x local variable):
$ java Test
Exception in thread "main" java.lang.VerifyError:
Bad type on operand stack in method Test.main([Ljava/lang/String;)V at offset 9
Just if you are curious, if you disable class verification, hell breaks loose:
$ java -Xverify:none Test
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.length(String.java:623)
at Test.main(Test.java:6)
Could've been worse.
Last but not least, there are plenty of opcodes dedicated to particular primitives (floats, doubles, ints, etc.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With