intern()在Java 6和Java 7中表现不同 [英] intern() behaving differently in Java 6 and Java 7

查看:182
本文介绍了intern()在Java 6和Java 7中表现不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class Test {
    public static void main(String...args) {
        String s1 = "Good";
        s1 = s1 + "morning";
        System.out.println(s1.intern());
        String s2 = "Goodmorning";
        if (s1 == s2) {
            System.out.println("both are equal");
        }
    }
}

此代码生成不同的输出Java 6和Java 7.
在Java 6中, s1 == s2 条件返回 false 并在Java中7 s1 == s2 返回 true 。为什么?

This code produces different outputs in Java 6 and Java 7. In Java 6 the s1==s2 condition returns false and in Java 7 the s1==s2 returns true. Why?

为什么这个程序在Java 6和Java 7中产生不同的输出?

Why does this program produces different output in Java 6 and Java 7?

推荐答案

似乎JDK7流程实习生的方式与以前不同。

我用build 1.7.0-b147对它进行了测试并得到了两者都相等,但在执行时(同样)字节码)与1,6.0_24我没有收到消息。

它还取决于字符串b2 = ... 行位于源代码。以下代码也不输出消息:

It seems that JDK7 process intern in a different way as before.
I tested it with build 1.7.0-b147 and got "both are equal", but when executing it (same bytecode) with 1,6.0_24 I do not get the message.
It also depends where the String b2 =... line is located in the source code. The following code also does not output the message:

class Test {
   public static void main(String... args) {
      String s1 = "Good";
      s1 = s1 + "morning";

      String s2 = "Goodmorning";
      System.out.println(s1.intern());  //just changed here s1.intern() and the if condition runs true   

      if(s1 == s2) {
         System.out.println("both are equal");
      } //now it works.
   }
}

好像实习生在其字符串池中未找到String后,将实际实例s1插入池中。创建s2时,JVM正在使用该池,因此它获得与s1相同的引用。另一方面,如果首先创建s2,那么该引用将存储到池中。

这可能是将实现的字符串从Java堆的永久生成中移出的结果。

it seems like intern after not finding the String in its pool of strings, inserts the actual instance s1 into the pool. The JVM is using that pool when s2 is created, so it gets the same reference as s1 back. On the other side, if s2 is created first, that reference is stored into the pool.
This can be a result of moving the interned Strings out from the permanent generation of the Java heap.

在此处找到:在JDK 7中解决的重要RFE


在JDK 7中,永久性字符串不再分配给永久性字符串生成Java堆,而是分配在Java堆的主要部分(称为年轻和老一代),以及应用程序创建的其他对象。此更改将导致更多数据驻留在主Java堆中,并且永久生成中的数据更少,因此可能需要调整堆大小。由于此更改,大多数应用程序只会看到堆使用中的相对较小的差异,但是加载许多类或大量使用String.intern()方法的较大应用程序将看到更显着的差异。

In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.

不确定这是一个错误,哪个版本... JLS 3.10.5状态

Not sure if that is a bug and from which version... The JLS 3.10.5 states


显式实现计算字符串的结果与具有相同内容的任何预先存在的文字字符串的字符串相同。

The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.

所以问题是预先存在的解释,编译时或执行时间:预先存在的Goodmorning或不是吗?

我更喜欢7之前WAS实现的方式......

so the question is how pre-existing is interpreted, compile-time or execute-time: is "Goodmorning" pre-existing or not?
I prefer the way it WAS implemented before 7...

这篇关于intern()在Java 6和Java 7中表现不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆