Java类常量池重复?

我用javap反编译了一个类,我在常量池部分看到了一些重复内容,如下所示:

 #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;

这个类是否按照类文件格式正确? 我认为每一个类只是被提及一次,并在其后的字节码部分索引。

$ javac -version
javac 1.7.0_15

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


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

这绝对是一个错误。 看一下这个。 有人已经记录这个错误,并已被承认>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6746955

已更新:

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

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

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

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

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

所以 ,讲述故事的道理,JVM确保两个不同的对象即使它们的哈希码是相同的,也永远不会相同。


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

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


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

java.lang.IncompatibleClassChangeError: incompatible InnerClasses attribute between …
链接地址: http://www.djcxy.com/p/71603.html

上一篇: Java class constant pool duplicates?

下一篇: Android Navigation Drawer