当前位置: 首页 > 面试题库 >

intern()在Java 6和Java 7中的行为有所不同

洪高刚
2023-03-14
问题内容
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。为什么?

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


问题答案:

似乎JDK7处理实习生的方式与以前不同。
我用版本1.7.0-b147进行了测试,结果“都是相等的”,但是用1,6.0_24执行它(相同的字节码)时,我没有得到消息。
它还取决于该String b2 =...行在源代码中的位置。以下代码也不会输出该消息:

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.
   }
}

似乎intern在其字符串池中找不到String之后,将实际实例s1插入池中。创建s2时,JVM正在使用该池,因此它获得与s1相同的引用。另一方面,如果首先创建s2,则该引用将存储到池中。
这可能是由于将永久字符串从Java堆的永久生成中移出的结果。

在这里找到:JDK
7中解决的重要RFE

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

不知道这是一个错误,以及从哪个版本开始……JLS 3.10.5声明

显式内联计算所得字符串的结果是与任何具有相同内容的现有文字字符串相同的字符串。

因此,问题是如何在编译时或执行时解释预先存在的内容:“ Goodmorning”是否预先存在?
我更喜欢7之前实现的方式…



 类似资料:
  • 几天来,我一直在用头撞这个,完全被难倒了。下面是纲要: 我有一个Eclipse插件项目,使用Tycho通过Maven 3构建 在Maven中,我已经设置了maven-jarsigner-plugin来使用我的keystore对jars进行签名(有关keystore的详细信息,请参阅下文) 我的密钥库里有个Thawte签名的代码签名证书 我可以从目标/*中获取任何签名的jar文件,并在上面运行“ja

  • 问题内容: 在Java 8中,此行产生,而在Java 9中,它产生。 这对于我们的遗留代码有一些严重的问题,是否有某种方法可以还原行为? 问题答案: 在我的jdk-9.0.4上运行此打印 yyyy-MM-dd 您可能想在命令行上使用属性设置,它不会有任何区别。 在Java 9中,来自Unicode联盟的通用语言环境数据存储库(CLDR)被用作语言环境数据的默认源,而在早期的Java版本中则不是这种

  • 问题内容: 从String类的javaDocs的intern方法中: 调用intern方法时,如果池已经包含等于equals(Object)方法确定的此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。 考虑以下用例: 有人可以解释为什么 是 正确的, 而以下是 错误的 : 问题答案: 七是您第一次使用字符串’hello2’。因此

  • java版本“1.6.0_37”java(TM)SE运行时环境(build 1.6.0_37-B06-434-11M3909)java HotSpot(TM)64位服务器VM(build 20.12-B01-434,混合模式) 如果在尝试安装java应用程序(LatexDraw)时总是出现错误,那么terminal上的版本6就不会有问题: :CGContextGetCTM:无效上下文0x0 :CG

  • 问题内容: 我正在将代码从Java(1.6)手动转换为C#,并发现原语(int和double)的行为有些困难。在C#中,似乎几乎所有转换都是自动发生的 但是在Java中,只允许其中一些 对于系统分析差异和任何基本原理,我将不胜感激。 问题答案: 在您的C#示例中,没有装箱或拆箱(和自动装箱)操作。 只是的别名 。 在Java中,装箱是必需的。因为类型擦除,你不能创建,只。在编译时,将变成,并且需要

  • 问题内容: 首先,我希望这不是问题,所以我开始了一个新话题。我不知道如何根据已经回答的问题提出问题,所以我做到了。 我对Java很陌生,以下是我的问题。我正在编写一个小型聊天程序,并且使用带有的来显示不同颜色的文本,显示笑脸和显示超链接。 我的问题是,经过一些研究,我发现问题可能是由于Java7造成的,我无法使换行器正常工作。我希望文本自动换行,并包裹在超出组件宽度的字符串中间。自动换行可以很好地