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

Jai*_*Das 7 java string object

String str1="JAVA";
String str2="JAVA";
String str3=new String("JAVA");
String str4=new String("JAVA").intern();
Run Code Online (Sandbox Code Playgroud)

将创建2个对象.str1并且str2因为String文字池概念而引用同一个对象并str3指向新对象,因为使用new运算符并str4指向同一个对象,str1并且str2因为intern()方法将字符串池检查到具有相同值的字符串.

str1=str2=str3=str4=null;
Run Code Online (Sandbox Code Playgroud)

一个对象将有资格获得GC.这是通过创建的对象String str3=new String("JAVA").始终可以通过存储在字符串文字池中的引用访问第一个String对象.

我的解释是否正确?

T.J*_*der 12

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

三:实习池中的一个通过文字和你创建的两个创建new String.

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

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

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

    String str3=new String("JAVA");
    
    Run Code Online (Sandbox Code Playgroud)

    (因为你以后设置str3null).

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

    String str4=new String("JAVA").intern();
    
    Run Code Online (Sandbox Code Playgroud)

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

  3. 可能,最终,在正确的条件下,甚至是实习池中的字符串.流行的看法相反,在实习生池串可用于垃圾收集,我们可以看到从这个问题的答案的其他问题.仅仅因为它们属于permgen(除非你使用的是Oracle的JVM 7或更高版本),这并不意味着它们不是GC,因为permgen也是GC的.所以问题变成:何时或如何在代码中使用的字符串文字不再被引用?我不知道答案,但我认为一个合理的假设是:何时以及如果使用它的类是从内存中卸载的.根据这个其他答案,只有在卸载类及其类加载器时才会发生(并且可能不会发生).如果类是由系统类加载器加载的(正常情况),那么可能它永远不会被卸载.

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

  • @TJCrowder我们不应该将"Java"与"OpenJDK HotSpot JVM"等同起来,有关PermGen和字符串常量的详细信息仅适用于后者(甚至可能不是所有的执行模式).Java规范中没有任何内容. (2认同)