【问题标题】:How does intern work in the following code?实习生如何在以下代码中工作?
【发布时间】:2015-10-28 19:04:03
【问题描述】:
String a = "abc";
String b = a.substring(1);
b.intern();
String c = "bc";
System.out.println(b == c);

这个问题可能很愚蠢,因为实习生在这里没有主要用途,但我仍然对这个事实感到困惑,为什么b == c 结果true

什么时候

String b = a.substring(1)

被执行,字符串b引用具有"bc"的对象

b.intern 是否在字符串常量池中创建文字 "bc",即使创建了,b==c 怎么会导致 true

【问题讨论】:

标签: java string literals


【解决方案1】:

String b = a.substring(1); 返回包含 "bc" 的字符串实例,但此实例不是字符串池的一部分(默认情况下,只有文字是内部的,通过 new String(data) 创建并从 substringnextLine 等方法返回的字符串是默认情况下不实习)。

现在当你调用

b.intern();

此方法检查字符串池是否包含等于存储在b(即“bc”)中的字符串,如果不是,则将该字符串放在那里。所以正弦池中没有代表"bc"的字符串,它将把来自b的字符串放在那里。

所以现在字符串池包含"abc""bc"

因为当你打电话时

String c = "bc";

表示bc 的字符串文字(与b 参考中的相同)将从池中重用,这意味着bc 将拥有相同的实例

这确认了b==c 的结果,返回true

【讨论】:

  • 但是字符串b指向的是一个包含“bc”的对象,b.intern();只需将“bc”放入字符串池中,当我们执行 String c = “bc”时,它会从字符串池中获取引用,而字符串 b 指向包含“bc”的对象。 b 和 c 如何包含相同的引用。请让我知道我哪里错了
  • 我不是投票者,但是这个 "So sine there's no string代表 "bc" in pool" 听起来不对,因为"bc" 已经在池中,因为该文字(来自String c = "bc")将在类加载期间被实习。
  • @Tom 请注意 String c = "bc"b.intern(); 之后,因此之前没有 "bc" 文字。
  • 这没什么大不了的,因为编译器会将每个字面量写入一个常量池中,该常量池何时会在类加载期间由 JVM 加载和实习。
  • @Tom 不完全是。字符串池在运行时填充,编译器可以不生成类中使用的文字列表。第一次创建字面量时,字符串池中会充满元素。
【解决方案2】:

String#intern()方法的文档

当调用 intern 方法时,如果池中已经包含一个等于该 String 对象的字符串,由 equals(Object) 方法确定,则返回池中的字符串。否则,将此 String 对象添加到池中并返回对该 String 对象的引用。

现在跟随 cmets

    String b = a.substring(1);  // results "bc"
    b.intern();                 // check and places "bc" in pool
    String c = "bc";            // since it is a literal already presented in pool it gets the reference of it
    System.out.println(b == c);// now b and c are pointing to same literal

【讨论】:

  • 投反对票,请解释一下是什么原因?
  • 感谢您的快速回复,但字符串 b 是否仍然指向内存中具有 bc 的对象? b.intern 从字符串池返回引用,但我们没有将引用保存在任何地方
  • 调用b.intern()b 没有任何作用,但它会将它引用的字符串的副本放入字符串池中。运行此代码的结果将是false。代码应该有b = b.intern();
  • Arjit 和@EJP 注意文档行Otherwise, this String object is added to the pool 这里指的是b
  • @EJP intern 将池中的字符串 equal 返回到我们的字符串。如果池已经有不同的字符串等于来自b 的字符串,那么将返回不同的字符串,但如果池不包含这样的字符串,来自b 的字符串将被放入池中,然后返回b = b.intern()在这种情况下与b.intern() 相同(因为intern 将返回b 持有的实例)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-27
  • 2011-08-18
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多