字符串池对象

时间:2015-05-30 07:49:31

标签: java string

请您澄清一下,在下面的案例中会创建多少个对象,为什么?我对此略感不安。

String s1 = "cat";

String s2 = "cat";

String s3 = "c"+"at";

String s4 = new String("cat");

String s5 = "kitty"+"cat";

String s6 = new String("kittycat");

String s7 = s5;

String s8= new String(s5); // Newly Added in this Question

2 个答案:

答案 0 :(得分:8)

让我们一步一步看:

String s1 = "cat";
String s2 = "cat";

这两个将是javac编译器在类文件中创建的相同常量池条目。加载此类时,此字符串(以及所有其他常量池字符串)将自动实现,因此它也将与其他类中的其他"cat"字符串合并。

String s3 = "c"+"at";

这实际上是相同的:如果在编译期间可以计算字符串连接,则由javac完成。所以它与s1s2几乎相同。这由JLS涵盖chapter 15.18.1

  

String对象是新创建的(第12.5节),除非表达式是常量表达式(第15.28节)。

String s4 = new String("cat");

在此明确创建一个新对象。 Java语言保证当您使用new关键字时,您将拥有一个新的不同对象,该对象不能与先前创建的任何对象相同。但是,如果仅在当前方法中使用此对象(或者在可以内联到当前方法中的方法中)并且不使用==操作将其与其他字符串进行比较,则JIT编译器可以跳过对象分配以进行优化。但是,如果您实际使用==System.identityHashCode,或者此方法作为解释帧执行,那么它实际上将是新对象。

传递给参数的"cat"字符串实际上是与s1s2s3相同的对象。

String s5 = "kitty"+"cat";

这类似于s3:javac编译器只会在编译期间创建一个"kittycat"字符串。查看字节码,您甚至不知道源中存在串联。

String s6 = new String("kittycat");

这与s4类似:显式创建新对象。如果您稍后尝试使用s6 == "kittycat",则会获得false

String s7 = s5;

在这里,您只需为先前创建的s5字符串分配引用,因此此处不会创建新对象。

所以答案是:最多会创建4个字符串,但在某些情况下,它可以优化到2个字符串。最重要的是:如果你试图检查同一个程序中有多少个字符串(即不使用Java代理或分析内存转储),你将总是得到四个。

答案 1 :(得分:0)

user3360241 - 您的回答似乎是正确的......不确定为什么在没有给出任何解释的情况下被投票结果如果......如果您这样做,那么这个数字将是两个......

Set<Integer> set = new HashSet<Integer>();

set.add(s1.hashCode());
set.add(s2.hashCode());
set.add(s3.hashCode());
set.add(s4.hashCode());
set.add(s5.hashCode());
set.add(s6.hashCode());
set.add(s7.hashCode());

System.out.println("size :: "+set.size());
相关问题