繁体   English   中英

Java类常量池重复?

[英]Java class constant pool duplicates?

我用javap反编译了一个类,我在Constant Pool部分看到了一些重复项,如下所示:

 #19 = Class              #350          //  java/lang/StringBuilder
... Some other class constants here
#318 = Class              #350          //  java/lang/StringBuilder

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;

根据类文件格式,这个类是否正确? 我认为每个Class只提到一次,后面由字节码部分的索引引用。

$ javac -version
javac 1.7.0_15

另一个奇怪的事情是在javac Pool.java中代表常量池的类的源代码中。 这表明它不会将对象放入池中(如果它已经存在)(借助HashMap)。 我想知道这些类的equals()/ hashCode()方法是否正确实现。

据我所知,从JVM规范中,没有这样的限制可以防止常量池中的重复条目。 通常,生成类文件的编译器没有重复项。 但即使类文件有重复项,它也不应影响其预期的行为。

你反编译的类文件是如何创建的?

你是对的。 Constant pool不需要重复的条目 一个类在常量池中只应有1个条目。

这肯定是一个错误。 看一下这个。 有人将此记录为bug并且已被确认>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6746955

答案已更新:

我想在这里指出的另一件事是添加重复的条目没有任何意义,因为它增加了类文件的字节大小,并且破坏了java类文件的紧凑性,可移植性和更快的网络移动性的主要目的。 类文件应尽可能紧凑。

顺便说一下 ,类文件是有效的,因为它遵循定义的类文件格式。 但它不是一个理想的。

我忘记了, 回答你的第二个问题:

JVM为相似的查找对象分配相同的哈希码,但它们仍然是不同的。 除非两者都指向同一对象,否则JVM永远不会创建两个相同的对象。 Hashcode只不过是一个分区系统。 类似的查找对象被放置在相同的分区中,以便在搜索特定对象时遍历时间变短。 Hashcode只是指向那个小分区的指针。

只是因为不可能为每个新对象分配不同的哈希码(因为对象的数量可能超过可能的唯一哈希码创建数量。请参考哈希算法中可能的冲突),您可能会发现具有相同哈希码的不同对象。 但事实上,在内存中指向同一引用的2个对象必须具有相同的哈希码。

因此 ,故事的道德,JVM确保两个不同的对象永远不会相同,即使它们的哈希码是。

注意:根据JENKINS-22525 ,似乎虽然具有此类重复项的类文件在技术上是合法的,但IBM的J9 VM在某些情况下会拒绝加载其内部类,

java.lang.IncompatibleClassChangeError: incompatible InnerClasses attribute between …

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM