我已经反编译了一个类,javap我在Constant Pool部分看到了一些重复,如下所示:
#19 = Class #350 // java/lang/StringBuilder
... Some other class constants here
#318 = Class #350 // java/lang/StringBuilder
Run Code Online (Sandbox Code Playgroud)
Methodrefs仅指其中一个:
#20 = Methodref #19.#351 // java/lang/StringBuilder."<init>":()V
#22 = Methodref #19.#353 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#24 = Methodref #19.#355 // java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
#25 = Methodref #19.#356 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#110 = Methodref #19.#445 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
Run Code Online (Sandbox Code Playgroud)
根据类文件格式,这个类是否正确?我认为每个Class只提到一次,后面由字节码部分的索引引用.
$ javac -version
javac 1.7.0_15
Run Code Online (Sandbox Code Playgroud)
另一个奇怪的事情是在javac Pool.java中代表常量池的类的源代码中.这表明它不会将对象放入池中(如果它已经存在)(借助HashMap).我想知道这些类的equals()/ hashCode()方法是否正确实现.
你是对的。Constant pool不需要重复条目。一个类在常量池中只能有 1 个条目。
这看起来绝对是一个错误。看一下这个。有人已将此记录为错误并且已被确认 >> https://bugs.java.com/bugdatabase/view_bug?bug_id=6746955
答案更新:
我想在这里指出的另一件事是,添加重复条目没有任何意义,因为它增加了类文件的字节大小,并且破坏了 java 类文件的紧凑性、可移植性和更快的网络移动性的主要目的。类文件应该尽可能紧凑。
顺便说一句,类文件是有效的,因为它遵循定义的类文件格式。但这并不是一个理想的。
我忘记了,回答你的第二个问题:
JVM 为看起来相似的对象分配相同的哈希码,但它们仍然是不同的。JVM 永远不会创建两个相同的对象,除非它们都引用同一个对象。哈希码只不过是一个分区系统。外观相似的对象被放置在同一分区中,以便在搜索特定对象时遍历时间变得更少。哈希码只不过是指向该小分区的指针。
只是因为不可能为每个新对象分配不同的哈希码(因为对象的数量可能超过创建唯一哈希码的可能数量。请参阅哈希算法中可能的冲突),您可能会发现具有相同哈希码的不同对象。但事情是这样的,指向内存中相同引用的两个对象必须具有相同的哈希码。
因此,从这个故事的寓意来看,JVM 确保两个不同的对象永远不会相同,即使它们的哈希码相同。
| 归档时间: |
|
| 查看次数: |
813 次 |
| 最近记录: |