是的,字節碼也是類型安全的。首先,有是垂頭喪氣使用每次一個字節代碼instruction called checkcast
:
Object obj = "abc";
String s = (String)obj;
被翻譯成:
aload_1
checkcast #3 // class java/lang/String
astore_2
其次invokevirtual
和別人期望給定類型的對象。如果你傳遞了錯誤的類型,JVM將拒絕加載這樣的類。我不認爲它是用Java語言實現的,所以我做了一些黑客攻擊。下面的代碼:
Integer x = 1;
String s = "abc";
int len = s.length();
被翻譯成:
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
加載s
局部變量通知指令8
。使用十六進制編輯器我換成aload_2
與aload_1
,從而試圖調用String.length()
一個Integer
對象(x
局部變量)上:
$ 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
只是如果你很好奇,如果禁用類驗證,地獄破散:
$ 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)
可能會變得更糟。
最後但並非最不重要的,有大量的專用於特定的基元的操作碼(浮點,雙精度數整數等)
編譯後不存在泛型。 – Mob