Java String intern()方法
这篇文章深入介绍了Java String intern()方法,该方法与Java中的"内部"字符串概念以及Java中的String池维护紧密相关。
Java中的字符串interning
在Java中,字符串文字是" interned"的,以便共享唯一的实例。最初为空的字符串池由String类私有维护。对于每个字符串文字(用双引号引起来的字符串值),JVM都会在字符串池中扫描具有相同值的任何字符串(如果返回的是相同的引用)。因此,不会为相同的字符串分配新的内存,而是使用现有的内存并共享引用。
让我们看一个例子。如果按以下方式创建两个字符串,则:
String str1 = “Hello” String str2 = “Hello”
然后两个对象都引用相同的内存。
字符串中的intern方法
字符串文字在Java中默认为Internated,但对于使用new运算符创建的字符串则不是这样。对于此类String实例,内存是在堆上分配的,而不是在String池中分配的。
例如,如果创建四个字符串,如下所示:
String str1 = “Hello”; String str2 = “Hello”; String str3 = new String(“Hello”); String str4 = new String(“Hello”);
str1和str2在常量字符串池中共享相同的引用,其中str3和str4对堆上的内存位置具有单独的引用。
即使对于使用new运算符创建的String,也可以使用Java String中的intern()方法从池中获取String对象(如果已经存在相同的值)。
- public String intern()–返回字符串对象的规范表示。调用intern方法时,如果池已经包含等于equals(Object)方法确定的此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。
Java intern()方法示例
让我们尝试借助几个示例来了解字符串实习。
public class StringInterning { public static void main(String[] args) { // Stored in String pool String str1 = "Hello"; // Stored in String pool String str2 = "Hello"; // Stored in heap String str3 = new String("Hello"); // returns true if(str1 == str2) { System.out.println("str1 and str2 are pointing to same memory reference"); }else{ System.out.println("str1 and str2 are not pointing to same memory reference"); } // returns false if(str1 == str3) { System.out.println("str1 and str3 are pointing to same memory reference"); }else{ System.out.println("str1 and str3 are not pointing to same memory reference"); } // shares the reference in String pool String str4 = str3.intern(); // returns true if(str1 == str4) { System.out.println("str1 and str4 are pointing to same memory reference"); }else{ System.out.println("str1 and str4 are not pointing to same memory reference"); } } }
输出:
str1 and str2 are pointing to same memory reference str1 and str3 are not pointing to same memory reference str1 and str4 are pointing to same memory reference
在示例中,字符串str1和str2创建为字符串文字,并且具有相同的值,因此这两个对象在字符串池中共享相同的引用。这就是为什么使用相等运算符('==')比较它们会返回true的原因。
字符串str3是使用new运算符创建的,因此它的内存在堆中分配。即使str3与str1和str2具有相同的值,但它不会共享相同的引用。这就是为什么使用相等运算符('==')将String str3与str1或者str2比较时返回false的原因。
字符串str4是使用intern方法创建的,因此如果这样的值已经存在,它将查找字符串池。由于值" Hello"已经在池中,因此str4与str1和str2共享引用。这就是为什么使用相等运算符('==')比较str4与str1或者str2会返回true的原因。
这是另一个使用intern()方法的Java程序。
public class StringInterning { public static void main(String[] args) { // Stored in heap String str1 = new String("Hello"); // Stored in heap String str2 = new String("Hello"); // returns false if(str1 == str2) { System.out.println("str1 and str2 are pointing to same memory reference"); }else{ System.out.println("str1 and str2 are not pointing to same memory reference"); } String str3 = str1.intern(); // returns false if(str1 == str3) { System.out.println("str1 and str3 are pointing to same memory reference"); }else{ System.out.println("str1 and str3 are not pointing to same memory reference"); } // store in the pool String str4 = "Hello"; // returns true if(str3 == str4) { System.out.println("str3 and str4 are pointing to same memory reference"); }else{ System.out.println("str3 and str4 are not pointing to same memory reference"); } } }
输出:
str1 and str2 are not pointing to same memory reference str1 and str3 are not pointing to same memory reference str3 and str4 are pointing to same memory reference
在示例中,字符串str1和str2使用new运算符创建,因此创建了两个单独的对象。这就是为什么使用相等运算符('==')比较它们会返回false的原因。
字符串str3是使用intern()方法创建的,因此str3的内存在池中分配。这就是为什么使用相等运算符('==')将str3与str1或者str2比较时返回false的原因。
字符串str4创建为字符串文字,因此将检查字符串池以查看是否已存在该值。已经存在相同的值,因此str4与str3具有相同的引用。这就是为什么使用相等运算符('==')比较str3和str4返回true的原因。