什么是 Java String 实习生?

2022-08-31 05:22:05

Java中的字符串实习是什么,我什么时候应该使用它,为什么


答案 1

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern()

基本上,对一系列字符串执行String.intern()将确保具有相同内容的所有字符串共享相同的内存。因此,如果你有一个名字列表,其中“john”出现了1000次,那么通过实习,你可以确保只有一个“john”实际上被分配了内存。

这对于减少程序的内存要求非常有用。但请注意,缓存由 JVM 在永久内存池中维护,与堆相比,永久内存池的大小通常有限,因此,如果您没有太多重复值,则不应使用 intern。


有关使用 intern() 的内存约束的更多信息

一方面,您可以通过内部化字符串重复项来删除它们,这是事实。问题在于,内部化的字符串转到永久生成,这是 JVM 的一个区域,是为非用户对象保留的,如类、方法和其他内部 JVM 对象。此区域的大小是有限的,并且通常比堆小得多。在 String 上调用 intern() 具有将其从堆中移出到永久生成中的效果,并且您有可能耗尽 PermGen 空间。

-- 来自: http://www.codeinstructions.com/2009/01/busting-javalangstringintern-myths.html


从JDK 7(我的意思是在HotSpot中),有些东西已经发生了变化。

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

-- 来自 Java SE 7 的功能和增强功能

更新:从 Java 7 开始,中间字符串存储在主堆中。http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html#jdk7changes


答案 2

有一些“朗朗上口的面试”问题,例如,如果您执行下面的代码段,为什么您会得到相等的!

String s1 = "testString";
String s2 = "testString";
if(s1 == s2) System.out.println("equals!");

如果要比较字符串,则应使用 .上面的打印等于,因为编译器已经为您暂存了。您可以使用实习生方法自己实习字符串,如前面的答案所示。equals()testString