intern()
方法是 java.lang.String
类中的一个方法,用于在 Java 字符串常量池中添加字符串对象,并返回对字符串对象的引用。它的作用是将字符串对象添加到字符串常量池中,并且如果字符串常量池已经存在相同内容的字符串,则返回对该字符串的引用。
在 Java 中,字符串是不可变的,当我们频繁地创建字符串对象时,会产生很多相同内容的字符串对象,这样会占用大量的内存空间。为了节省内存,并提高字符串比较的效率,我们可以使用 intern()
方法将字符串对象添加到字符串常量池中,从而实现字符串对象的共享。
在 Java 1.6 版本中,字符串常量池是在永久代中分配的。当我们调用 intern()
方法时,JVM 会检查字符串常量池中是否存在相同内容的字符串,如果存在,则返回常量池中的字符串引用;如果不存在,则在常量池中创建一个新的字符串对象,并返回对该对象的引用。
但是,由于字符串常量池位于永久代,而永久代的内存是有限的,如果不断调用 intern()
方法添加字符串,会导致永久代内存溢出。因此,在 Java 1.6 版本中,如果字符串常量池中已经存在相同内容的字符串,就不会再创建新的字符串对象,而是直接返回常量池中的字符串引用。
在 Java 1.8 版本中,字符串常量池被移至堆中,使用了元空间(Metaspace)代替永久代。元空间是使用本地内存实现的,并且大小取决于系统可用的内存大小。
当我们调用 intern()
方法时,JVM 会检查字符串常量池中是否存在相同内容的字符串,如果存在,则返回常量池中的字符串引用;如果不存在,则在堆中创建一个新的字符串对象,并将对象的引用添加到字符串常量池中。
由于堆中的字符串对象是由垃圾回收器管理的,因此在 Java 1.8 中使用 intern()
方法添加字符串并不会导致内存溢出的风险。
下面是一个使用 intern()
方法的示例:
public class InternExample {
public static void main(String[] args) {
String str1 = new String("Hello");
String str2 = "Hello";
String str3 = str1.intern();
System.out.println(str1 == str2); // false
System.out.println(str2 == str3); // true
}
}
解释示例代码的执行过程:
str1
,其内容为 "Hello"。 str2
,其内容也为 "Hello"。由于字符串常量池中已经存在相同内容的字符串 "Hello" ,所以会直接返回该字符串的引用。 intern()
方法将 str1
的引用添加到字符串常量池中,并且返回对该字符串的引用,赋值给 str3
。 str1
和 str2
是不同的字符串对象,而 str2
和 str3
是相同的字符串对象。 intern()
方法可以将字符串对象共享,避免创建相同内容的字符串对象,减少内存占用。 ==
运算符进行引用地址的比较,减少了字符串的内容比较。 intern()
方 ✽✽ 在字符串常量池中创建额外的字符串对象,如果字符串常量池中已经存在相同内容的字符串,会浪费一定的内存空间。 intern()
方法,可能导致永久代内存溢出。 intern()
方法需要注意控制字符串的数量,避免导致内存溢出。 intern()
方 ✽✽ 将字符串添加到堆中,并不会导致内存溢出的风险。 intern()
方法是用于将字符串对象添加到字符串常量池中,并返回对字符串的引用。在 Java 1.6 版本中,字符串常量池位于永久代,使用 intern()
方法可能导致内存溢出;而在 Java 1.8 版本中,字符串常量池位于堆中的元空间,使用 intern()
方法不会导致内存溢出的风险。使用 intern()
方法可以节省内存和提高字符串比较的效率,但需要注意控制字符串数量和版本兼容性。
本文由 mdnice 多平台发布