字符串连接期间创建的对象数
有人可以告诉我在下面的代码中执行System.out.println
语句时将创建多少个对象
int i=0; int j=1; System.out.print("i value is "+ i + "j value is "+j);
如果你真的想知道发生了什么,为什么不看字节码呢?
我将你的代码包装在一个main函数中,编译它然后用javap -c Test.class
反汇编它。 这是输出(使用Oracle Java 7编译器):
Compiled from "Test.java" class Test { Test(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]); Code: 0: iconst_0 1: istore_1 2: iconst_1 3: istore_2 4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 7: new #3 // class java/lang/StringBuilder 10: dup 11: invokespecial #4 // Method java/lang/StringBuilder." ":()V 14: ldc #5 // String i value is 16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: iload_1 20: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 23: ldc #8 // String j value is 25: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 28: iload_2 29: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 32: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 35: invokevirtual #10 // Method java/io/PrintStream.print:(Ljava/lang/String;)V 38: return }
在此方法中分配的唯一对象是StringBuilder
(通过位置7处的new
指令)。 但是, invoke
d的其他方法本身可能会分配一些东西,我非常怀疑StringBuilder.toString将分配一个String
对象。
这将创建一个StringBuilder
对象(以及此对象在内部使用的任何对象),添加值,最后StringBuilder
将创建一个带有结果的String
对象。
代码
int i=0; int j=1; System.out.print("i value is "+ i + "j value is "+j);
创建3个对象。
我的原因:
Java中的基本数据类型不是对象,也不从Objectinheritance。 所以int i=0; and int j=1;
int i=0; and int j=1;
没有成为一个对象。
现在System.out.print("i value is "+ i + "j value is "+j);
其中包含不可变的String
,对字符串的操作很昂贵。我们可以将操作拆分为此。
("i value is ").concat(i) // creates one object let say obj1 obj1.concat("j value is ") //creates another let say obj2 obj2.concat(j) // creates the final string let say obj3;
在示例字符串操作中, str1.concat(str2)
通过使用两个String对象完成,它创建第三个并更改引用,使其产生错觉,即它实际上是第一个字符串对象,即str1。 因此str1将有一个新的String,它包含旧str1和str2连接的值。
这是我相信我有限的知识。 如果我错了,请纠正我。
只有1
,String对象被连接起来。
只有1即用于打印字符串。
Thumb规则 – 每当完成字符串的连接时,就会创建一个新对象。
编译器将代码转换为如下代码:
int i=0; int j=1; StringBuilder temp = new StringBuilder(); // creates a StringBuilder temp.append("i value is "); // creates or re-uses a String temp.append(i); // might create a String temp.append("j value is"); // creates or re-uses a String temp.append(j); // might create a String String temp2 = temp.toString(); // creates a String System.out.print(temp2);
这取决于你是否计算“i value is”和“j value is”字符串,它们被创建一次然后重新使用。
如果你计算它们,那么至少4,否则至少2。
实际上,每个String都有自己的char [],它实际上存储了字符串。 所以这是7或3,而不是4或2。
StringBuilder也有一个char [],当你向它添加更多数据时可能需要创建新的char []。 String.valueOf或System.out.print也可能会创建背后的对象,如果没有外部工具, 您无法了解它们 。 因此“至少”。
如果它确实依赖于实现,那么如果它被评估为:
StringBuilder sb = new StringBuilder("i value is "); sb.append(i); sb.append(j); String newStr = sb.toString();
将有2个对象。
字符串是不可变的意味着您无法更改对象本身。
每次创建新的字符串对象时执行连接。
所以在上面的例子中
- int i
- int j
- “我的价值是”
- “我的价值是”+我
- “我的价值是”+ i +“j值是”
- “我的价值是”+ i +“j值是”+ j
在上面的示例中创建了总共六个对象。
5个对象
- “我的价值是”。将形成一个String对象。
- “我的价值是” + i 。这个连接操作将形成第二个对象。
- “j值是”将形成第三个对象。
- “我的值是”+ i + “j值是”。第四个因为连接而形成的对象。
- “我的值是”+ i +“j值是” + j。这最后的连接将形成第5个对象。