在此过程中创建的String对象总数?

时间:2013-06-29 07:14:01

标签: java string object

String str1="JAVA";
String str2="JAVA";
String str3=new String("JAVA");
String str4=new String("JAVA").intern();

将创建2个对象。 str1str2引用同一个对象,因为字符串文字池概念和str3指向新对象,因为使用new运算符和str4指向同一个对象指向{{ 1}}和str1因为str2方法检查字符串池中是否有相同值的字符串。

intern()

一个对象将有资格获得GC。这是通过str1=str2=str3=str4=null; 创建的对象。第一个String对象始终可以通过存储在字符串文字池中的引用来访问。

我的解释是否正确?

1 个答案:

答案 0 :(得分:12)

  

在流程中创建的String对象总数?

三:通过文字创建的实习池中的一个以及您通过new String创建的两个。

  

一个对象将有资格获得GC。

我在非常的特殊情况下计算两个,甚至可能全部三个:

  1. 您在此行中创建的那个:

    String str3=new String("JAVA");
    

    (因为您之后将str3设置为null)。

  2. 您在此行中暂时创建的那个:

    String str4=new String("JAVA").intern();
    

    该行创建一个新的String对象,在其上调用intern,然后保存对池中字符串的引用。因此理论上,它会创建一个可立即用于GC的String对象。 (JVM可能足够聪明,不能这样做,但这就是理论。)

  3. 最终,在合适的条件下,甚至是实习生池中的字符串。与流行的看法相反,实习池中的字符串可用于垃圾收集,我们可以从the answer to this other question看到。仅仅因为它们属于permgen(unless you're using Oracle's JVM 7 or later)并不意味着它们不是GC,因为the permgen is GC'd too。所以问题就变成了:代码中使用的字符串 literal 何时或如何不再被引用?我不知道答案,但我认为合理的假设将是:何时以及如果使用它的类是从内存中卸载的。根据{{​​3}},只有在卸载类及其类加载器时才会发生这种情况(即使这样也可能不会发生)。如果类是由系统类加载器加载的(正常情况),那么可能它从未被卸载。

  4. 所以几乎可以肯定只有两个(上面的#1和#2),但同时也很有趣地看着#3。