String intern方法与普通字符串创建之间的区别

时间:2018-04-07 14:21:17

标签: java string

我无法理解String类对intern方法提供程序的使用。

String s1 = "vivek"; //Stmt 1
String s2 = "vivek"; //Stmt 2
String s3 = s1.intern(); //Stmt 3

System.out.println(s1 == s2);// prints true
System.out.println(s1 == s3);// prints true

我读到内部编译器做一个实习生,但在哪个对象上?编译器如何知道他必须为s1实习生创建s2

Stmt 2Stmt 3之间的区别是什么?两者都一样吗?如果是,那么java的intern方法有什么特别之处?

3 个答案:

答案 0 :(得分:3)

不同之处在于变量的初始化方式决定了保存变量的位置;

  1. 如果它具有相同的值和相同的初始化方法并使用new关键字初始化 - 它会将它保存在堆中,并将每个变量保存为新对象,即使它具有相同的值。
  2. 如果它具有相同的值和相同的初始化方法并直接初始化 - 它将在JVM池化内存中引用它。
  3. String Interning Oracle参考。

    构造字符串有两种方法:通过赋值字符串文字或通过new运算符和构造函数显式创建String对象来进行隐式构造。例如

    String s1 = "Hello";              // String literal
    String s2 = "Hello";              // String literal
    String s3 = s1;                   // same reference
    String s4 = new String("Hello");  // String object
    String s5 = new String("Hello");  // String object
    

    Java提供了一种特殊的机制来保持String文字 - 在一个所谓的字符串公共池中。如果两个字符串文字具有相同的内容,则它们将在公共池内共享相同的存储。采用这种方法来节省常用字符串的存储空间。另一方面,通过new运算符和构造函数创建的String对象保留在堆中。堆中的每个String对象都有自己的存储空间,就像任何其他对象一样。

    enter image description here

    s1 == s1;         // true, same pointer
    s1 == s2;         // true, s1 and s1 share storage in common pool
    s1 == s3;         // true, s3 is assigned same pointer as s1
    s1.equals(s3);    // true, same contents
    s1 == s4;         // false, different pointers
    s1.equals(s4);    // true, same contents
    s4 == s5;         // false, different pointers in heap
    s4.equals(s5);    // true, same contents
    

    重要说明:

    1. 在上面的例子中,我使用了关系等式运算符' =='比较两个String对象的引用。这样做是为了演示在公共池中共享存储的字符串文字与在堆中创建的String对象之间的差异。在程序中使用(str1 == str2)来比较两个字符串的内容是一个逻辑错误。
    2. 可以通过直接分配在公共池中共享的字符串文字来创建字符串。这种情况并不常见,不建议使用new运算符在堆中构造String对象。

答案 1 :(得分:2)

因为当你创建一个字符串时:String s1 =“vivek”; 此字符串在字符串常量池中创建,引用返回“s1”。

当您使用intern方法创建一个字符串时:s3 = s1.intern(); 此intern方法仅返回字符串常量池中的引用。 这就是为什么两个字符串都相同,都包含对同一字符串对象的引用。

参考下图: enter image description here

但是如果你创建一个像:

这样的字符串
String s1=new String("vivek"); //---here one "vivek" will be stored in string constant pool and second "vivek" will be stored in heap area and "s1" contains reference to string in heap area 

String s2="vivek";  
String s3=s1.intern();//returns string from pool, now it will be same as s2  
System.out.println(s1==s2);//false because reference is different  
System.out.println(s2==s3);//true because reference is same  

答案 2 :(得分:2)

intern()方法在Java中做什么?

new 运算符创建的字符串对象默认情况下不会添加到字符串池中,而不是字符串文字。实习方法允许将String对象放入池中。您可以使用 intern()方法实现String对象,并将它们存储到String池中以便进一步重用。例如,当您创建字符串文字时,例如 String s1 =“abc”,它会自动存储在String池中,但是当您创建一个新的String对象时,例如 String s1 = new String(“abc”),即使它是相同的String,也会创建不同内存位置的新对象。这是一个重复的字符串。通过在此对象上调用 intern()方法,可以指示JVM将此String放入池中,并且每当其他人创建“abc”时,将返回此对象而不是创建新对象。这样,您可以在Java中节省大量内存,具体取决于程序中重复的字符串数量。 例如:

String s4 = new String("abc");
s4 = s4.intern();
String s5 = "abc";
System.out.println(s4==s5); // true

当您尝试在字符串常量池中使用intern方法并且引用相同的引用时,我认为在您的方案中没有使用intern方法。 你会发现更多信息here 希望这会对你有帮助......