有人可以告诉我在执行以下代码中的System.out.println
语句时将创建多少个对象
int i=0;
int j=1;
System.out.print("i value is "+ i + "j value is "+j);
答案 0 :(得分:7)
如果你真的想知道发生了什么,为什么不看字节码呢?
我将代码包装在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."<init>":()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."<init>":()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
对象。
答案 1 :(得分:5)
这将创建一个StringBuilder
对象(以及此对象在内部使用的任何对象),添加值,最后StringBuilder
将创建一个带有结果的String
对象。
答案 2 :(得分:2)
代码
int i=0;
int j=1;
System.out.print("i value is "+ i + "j value is "+j);
创建3个对象。
我的理由:
Java中的基本数据类型不是对象,不会从Object继承。所以
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连接的值。
这是我相信我有限的知识。如果我错了,请纠正我。
答案 3 :(得分:1)
只有1
,String对象才会被连接。
答案 4 :(得分:1)
如果它确实依赖于实现,那么如果它被评估为:
StringBuilder sb = new StringBuilder("i value is ");
sb.append(i);
sb.append(j);
String newStr = sb.toString();
将有2个物体。
答案 5 :(得分:1)
仅用于打印字符串。
Thumb规则 - 每当完成字符串的连接时,就会创建一个新对象。
答案 6 :(得分:1)
编译器将代码转换为如下代码:
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也可能在你的背后创建对象,如果没有外部工具,你就无法了解它们。因此“至少”。
答案 7 :(得分:0)
字符串是不可变的意味着您无法更改对象本身。
每次创建新的字符串对象时执行连接
所以在上面的例子中
在上面的示例中创建了总共六个对象。
答案 8 :(得分:0)
5个对象
答案 9 :(得分:0)
您应该在这里考虑2点:
在这种情况下,以上答案是正确的。将创建五个String对象。