gpt4 book ai didi

java - 编译后 Java 对象引用变量类型会发生什么变化?

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:57:48 25 4
gpt4 key购买 nike

我不记得在 Java 字节码中见过任何引用变量类型的概念。我对类型删除有所了解,但这个术语似乎与泛型紧密相关,而我的问题是关于一般的对象引用变量。Java 对象引用变量类型是否在编译后仍然存在?还是变量类型仅起到帮助编译器帮助开发人员检查代码是否有意义的作用?如果引用变量类型在编译后幸存下来,它们会出现在字节码中的什么位置?

编辑:请允许我在这里感谢您所做的所有宝贵贡献。为了进一步缩小我的想法,我想添加一个示例:

Object o = "foo";

在字节码中,变量 o 及其类型 (Object) 会在任何地方表示并在运行时读取吗?

最佳答案

是的,字节码也是类型安全的。首先有一个字节码instruction called checkcast每次你沮丧时都会用到:

Object obj = "abc";
String s = (String)obj;

翻译成:

aload_1       
checkcast #3 // class java/lang/String
astore_2

其次,invokevirtual 和其他人期望给定类型的对象。如果传递了错误的类型,JVM 将拒绝加载此类。我不认为它可以用 Java 语言实现,所以我做了一些 hacking。以下代码:

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,从而尝试在 Integer 对象上调用 String.length() (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

只是如果你很好奇,如果你禁用类验证, hell 就会崩溃:

$ 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)

可能会更糟。


最后但同样重要的是,有大量专用于特定原语( float 、 double 、整数等)的操作码

关于java - 编译后 Java 对象引用变量类型会发生什么变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14666132/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com