【问题标题】:Can string pool contain two strings with the same value? [duplicate]字符串池可以包含两个具有相同值的字符串吗? [复制]
【发布时间】:2013-07-31 19:49:58
【问题描述】:

字符串池可以包含两个相同值的字符串吗??

String str = "abc";
String str1 = new String("abc");

   Will the second statement with `new()` operator creates two objects of `string` "abc", one on `heap` and another on `string` pool? 

   Now if i call intern() on str1 ie str1.intern(); as a third statement, will str1 refer to the "abc" from String pool? 

  If yes then what will happen to the object that was created on heap earlier by the new(). Will that object be eligible for garbage collection.?
  If no then what will be the result of str1.intern();?

【问题讨论】:

标签: java string


【解决方案1】:

第一个也不会创建一个对象,第二个也只会创建一个字符串对象。区别在于第一个将在字符串池中创建,第二个将仅在堆中创建。 如果你会调用 str1.intern(); 那么它将被添加到字符串池中。

String str1 = "abc";
String str2 = new String("abc");
Stirng str3 = "abc"

这里将创建两个对象。第一行将创建一个引用 str1 的强对象,第三行将指向在第一行创建的引用 str3 的同一对象,但在第二行将创建一个新对象,因为我们在这里使用 new 关键字。希望对你有帮助。

还要检查this 的答案。那里有很好的解释。

【讨论】:

  • 所以你的意思是说如果我按相反的顺序做语句,仍然会有两个对象?
  • @JunedAhsan 无论你做什么,都只会有两个对象。我编辑了一点我的答案。请再读一遍。
  • 不,这是错误的。如果即使使用 new 创建对象,它仍将是字符串池的一部分。如果后面跟着一个简单的字符串 ="sameStirng" 语句,则将使用池化对象,而不是创建新对象。
  • 否,如果您将在任何情况下使用 new,即使字符串池中存在另一个具有相同值的字符串,也会创建一个新对象。将稍微编辑答案。
  • 谁给我DV请解释一下!!!
【解决方案2】:

“abc”对象将在类加载时创建并放在字符串池中。第二行将使用 String(String original) 构造函数,其中 original 是指向池中“abc”的指针。这是第二行的字节码:

NEW java/lang/String
DUP
LDC "abc"
INVOKESPECIAL java/lang/String.<init>(Ljava/lang/String;)V
ASTORE 2

【讨论】:

    【解决方案3】:

    new String("abc") 是类实例创建表达式,必须创建一个新对象。它是否在内部与文字 "abc" 共享相同的 char 数组取决于 String 实现。两个“abc”引用都将使用相同的实习生字符串。

    【讨论】:

    • 文档说“新创建的字符串是参数字符串的副本”。听起来应该不允许发生 char[] 共享(即使不是 100% 明确)。
    • @MarkoTopolnik 文档中没有提到或要求使用 char[],因此“副本”注释不太可能适用于它,而不是 String 参数。在实践中,当且仅当 String 参数比它的数组短时,JDK 1.7 实现会制作数组的副本。这可能是子字符串操作的结果。
    • 是的,这就是为什么我说它不是 100% 明确的,但请注意:它不是说“新创建的String”,而是“新创建的字符串”。而实际的字符串存储在char[]中。
    【解决方案4】:
        String t1 = "ABC";
        String t2 = new String("ABC");
        String t3 = "ABC";
    
        System.out.println(t1 == t2);
        System.out.println(t2 == t3);
        System.out.println(t1 == t3);
    

    生成以下输出 (Java SE 7):

        false
        false
        true
    

    【讨论】:

      【解决方案5】:

      基本上是:

      // "abc" is interned by the JVM in the pool
      String str="abc"; 
      // JVM uses the pooled "abc" to create a new instance
      String str1=new String("abc"); 
      

      str1 仅创建一个新的 String 对象引用。 String 文字 "abc" 被 JVM 截留。由于字面量"abc" 已经存在于字符串池中,因此在第二个语句中,JVM 应该使用它。

      【讨论】:

      • // JVM uses the pooled "abc" to create a new instance - JVM 首先检查池中的文字,如果存在则使用该 JVM 在堆中创建字符串?
      • @sansix 这句话和我的有什么不同?
      • 我没有对你投反对票 - 我只是怀疑 - JVM should use 那个字面池值或 uses 那个值
      • @TheNewIdiot 嘿,我想知道所有这些。你怎么知道sureshatta对你投了反对票?有没有办法知道谁对你投了反对票?如果是的话,我们可以知道任何其他类似的功能吗?
      • 字符串 str = "abc";字符串 str1 = new String("abc");现在如果我在 str1 上调用 intern() 即 str1.intern();作为第三条语句,它将引用字符串池中的“abc”。那么之前new()在堆上创建的对象会发生什么。该对象是否有资格进行垃圾收集????
      猜你喜欢
      • 2019-01-12
      • 2015-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      相关资源
      最近更新 更多