【问题标题】:Java 7 - String.intern() behaviourJava 7 - String.intern() 行为
【发布时间】:2013-02-23 18:20:21
【问题描述】:

我已经阅读了this answer 关于如何检查一个字符串是否在 Java 中的实习,但我不明白以下结果:

String x = args[0]; // args[0] = "abc";
String a = "a";
String y = a + "bc";
System.out.println(y.intern() == y); // true

但是如果我声明一个字符串文字:

String x = "abc";
String a = "a";
String y = a + "bc";
System.out.println(y.intern() == y); // false

此外,没有任何字符串文字,args[0] 似乎直接被实习:

// String x = "abc";
String y = args[0];
System.out.println(y.intern() == y); // true (???)
// false if the first line is uncommented

为什么y.intern() == y 会根据x 是否为文字而改变,即使对于使用命令行参数的示例也是如此?

我知道literal strings are interned at compile time,但我不明白为什么它会影响前面的示例。我还阅读了一些关于字符串实习的问题,例如 String Pool behaviorQuestions about Java's String poolJava String pool - When does the pool change?。但是,他们都没有对这种行为给出可能的解释。

编辑:

我错误地写道,在第三个示例中,如果声明了String x = "abc";,结果不会改变,但确实如此。

【问题讨论】:

  • 我在所有情况下都是假的
  • 这种行为有点吓人……
  • @HotLicks - 仅当变量声明为 final 时。
  • @MartijnCourteaux - 不知道你为什么说“可怕”。给定的字符串值可能已经或可能尚未被实习 - 可能在一小时前采用不同的方法。此外,intern() 不能保证返回原始字符串,即使它是第一个这样的字符串 - 它可能会返回一个副本。

标签: java string java-7 pool


【解决方案1】:

这是因为y.intern() 会返回y,如果该字符串之前没有被保留。如果字符串已经存在,则调用将返回与y 最有可能不同的已经存在的实例。

但是,所有这些都高度依赖于实现,因此在不同版本的 JVM 和编译器上可能会有所不同。

【讨论】:

  • 那是不是意味着y.intern() == y在字符串已经被interned的时候是假的呢?和the answer to which I referred at the beginning不矛盾吗?
  • 如果一个等于 y 但是不同实例的字符串已经被实习,你会得到错误。如果与y 相同的实例以前被实习过,您将得到真实的结果。如果之前没有实习过等于 y 的字符串,您也会得到 true。
  • 它确实与答案相矛盾,但答案中的代码是错误的。应该是!= 来检查它是否已经被实习了。
  • @Jochen 这取决于答案是指myString 实例还是等于myString 的字符串
  • @Henry True。我想像这样一个看似简单的问题,如果没有冗长的解释,只用一行代码是不可能回答的:)
【解决方案2】:

实施细节可能不同。但这正是我所期望的行为。您的第一种情况意味着默认情况下命令行参数不被实习。因此y.intern()在实习后返回对y的引用。

第二种情况是 VM 自动实习文字,因此y.intern() 返回对x 的引用,这与y 不同。

最后一种情况再次发生,因为默认情况下没有任何东西被实习,所以对intern()的调用返回对y的引用 . 我认为更积极地实习 String 是合法的,但据我所知,这是规范要求的最低限度的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 2014-11-22
    • 2013-04-04
    • 2015-12-27
    • 2019-08-03
    • 1970-01-01
    • 2014-12-05
    相关资源
    最近更新 更多