能否请您澄清一下,在下面的案例中会创建多少个对象?为什么?我对此略感不安.
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
Run Code Online (Sandbox Code Playgroud)
让我们一步一步看:
String s1 = "cat";
String s2 = "cat";
Run Code Online (Sandbox Code Playgroud)
这两个将是javac编译器在类文件中创建的相同常量池条目.加载此类时,此字符串(以及所有其他常量池字符串)将自动实现,因此它也将与"cat"其他类中的其他字符串合并.
String s3 = "c"+"at";
Run Code Online (Sandbox Code Playgroud)
这实际上是相同的:如果在编译期间可以计算字符串连接,则由javac完成.所以它s1和and 几乎一样s2.这由JLS 第15.18.1章涵盖:
除非表达式是常量表达式(第15.28节),否则新创建String对象(第12.5节).
String s4 = new String("cat");
Run Code Online (Sandbox Code Playgroud)
在这里,您明确地创建一个新对象.Java语言保证在使用new关键字时,您将拥有一个新的不同对象,该对象不能与先前创建的任何对象相同.但是,如果仅在当前方法中使用此对象(或者在可以内联到当前方法中的方法中)并且不使用==操作将其与其他字符串进行比较,则JIT编译器可以跳过对象分配以进行优化.但是如果你实际使用==or System.identityHashCode,或者这个方法是作为解释帧执行的,那么它实际上就是新对象.
将"cat"被传递到的参数串实际是相同的对象s1,s2和s3.
String s5 = "kitty"+"cat";
Run Code Online (Sandbox Code Playgroud)
这类似于s3:javac编译器只会"kittycat"在编译期间创建一个字符串.查看字节码,您甚至无法知道源中存在串联.
String s6 = new String("kittycat");
Run Code Online (Sandbox Code Playgroud)
这类似于s4:显式创建新对象.如果您稍后尝试使用s6 == "kittycat",您将获得false.
String s7 = s5;
Run Code Online (Sandbox Code Playgroud)
在这里,您只需为先前创建的s5字符串分配引用,因此此处不会创建新对象.
所以答案是:最多会创建4个字符串,但在某些情况下,它可以优化到2个字符串.最重要的是:如果你试图检查同一个程序中有多少个字符串(即不使用Java代理或分析内存转储),你将总是得到四个.
| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |