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

Java的String.intern()的用途是什么?

彭英逸
2023-03-14
问题内容

我知道有两种在Java中创建String的方法:

String a = "aaa";
String b = new String("bbb");

通过第一种方式,Java一定会在字符串池中创建一个String对象并对其进行a引用。(假设“ aaa”以前不在池中。)

使用第二种方法,将在堆中创建一个对象,但是jvm还会在字符串池中创建一个对象吗?

在这篇关于Java的字符串池的问题中,@ Jesper说:

如果您这样做:

String s = new String("abc");

那么池中将有一个String对象,一个代表文字“ abc”的>,并且池中没有一个单独的String对象,其中包含池对象的>内容的副本。

如果是这样,则每次使用时,都会new String("bbb");在池中创建一个对象“
bbb”,这意味着通过上述两种方式,java始终会在池中创建一个字符串对象。那是intern()用来干什么的呢?在docs
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern()中,它说:

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

这意味着在某些情况下池中没有字符串,这可能吗?哪一个是对的?


问题答案:

我们的String对象可以通过两种基本方式进入池:

  • 在源代码(例如)中使用文字"bbb"
  • 使用intern

intern用于当您有一个String不是池中的其他对象时。例如:

String bb = "bbb".substring(1); // substring creates a new object

System.out.println(bb == "bb");          // false
System.out.println(bb.intern() == "bb"); // true

或略有不同:

System.out.println(new String("bbb").intern() == "bbb"); // true

new String("bbb") 确实创建了两个对象…

String fromLiteral = "bbb";                     // in pool
String fromNewString = new String(fromLiteral); // not in pool

…但更像是特例。它创建两个对象是因为"bbb"引用了一个对象:

字符串文字是对类String[…] 的实例的引用。

而且,字符串文字总是引用class的相同实例String

new String(...)创建它的副本。

但是,有许多String不使用文字即可创建对象的方式,例如:

  • 所有String执行某种突变的方法。(substringsplitreplace等)
  • String从诸如a Scanner或a之类的输入中读取a Reader
  • 至少一个操作数不是编译时常量时的串联。

intern使您可以将它们添加到池中,或检索现有对象(如果有)。在大多数情况下,String不需要s,但是可以将其用作优化,因为:

  • 它可以让您与比较==
  • 由于重复项可以被垃圾回收,因此可以节省内存。


 类似资料:
  • 问题内容: 我知道他们已经用Java 8中的MetaSpace替换了PermGen。但是我有几个问题: 默认情况下是否收集MetaSpace? 甚至PermGen都是通过添加args这样的GC收集的,那么什么使MetaSpace比PermGen更好呢? MetaSpace基于本机内存,因此它将Java对象保留在磁盘上而不是VM上吗? 甚至MetaSpace也会耗尽内存?如果是这样,我会得到的。 默

  • 问题内容: 所以,我看着这个“枚举”类型,并且它种好像一个华而不实的 数组 / / 给我。到底有什么用? 问题答案: 枚举是一种固定数量的常量,至少可以用于两件事 不变 这比创建一堆整数常量要好得多。 创建一个单例 您可以使用枚举来做一些有趣的事情,请看这里 也请看官方文档

  • 问题内容: 我不了解Java的这一功能。我知道它使编码更容易,有时看起来更整洁,但这的实际用途是什么?相反,我觉得最好显示警告,因为将来任何人在修改代码之前都可以引用它们。这@SuppressWarnings是否提高了编译效率,还是根据任何编码标准? 问题答案: 其他答案已经解释了很多用例,但是我想强调一点, 有时您绝对需要使用它来克服语言本身的局限性,在这些情况下,使用绝对是合法的。 在其他情况

  • 问题内容: java中有什么用? 请解释一下。 问题答案: 可能这个例子会帮助您。

  • 本文向大家介绍sinon.js的用途是什么?,包括了sinon.js的用途是什么?的使用技巧和注意事项,需要的朋友参考一下 SinonJS提供独立的测试间谍,存根和模拟。这是一个我们可以用来创建用于单元测试的对象模拟的库。 间谍-可以用来追踪执行情况的伪造函数。 存根-函数替换,我们可以从中返回所需的内容或使我们的函数以适合我们测试多个场景的方式工作。 嘲笑-假方法 所有这些对象都有助于对我们的代

  • 我试图理解何时应该使用stdio函数。 例如,如果我对有效的执行或,并得到一个短计数,并且为真,我该怎么办? 从我到目前为止所读到的,和是健壮的,并且会阻止和/或重试(如果有锁和/或中断可能发生在较低级别的函数中),所以使用<代码>clearerr()因为或错误将是如此灾难性,以至于没有必要尝试恢复。 另外,只告诉我有错误,而不是错误是什么。