链接方法与在Java中生成临时变量是否会影响内存分配?
在Java中,如果我在一个对象上执行多个方法,我可以链接它们,或者我可以创建一个临时变量,就像这样 锁链链接方法与在Java中生成临时变量是否会影响内存分配?,java,garbage-collection,heap-memory,allocation,Java,Garbage Collection,Heap Memory,Allocation,在Java中,如果我在一个对象上执行多个方法,我可以链接它们,或者我可以创建一个临时变量,就像这样 锁链 System.out.println( str.substring(0,4).substring(0,2)); 温度变量 String tmp = str.substring(0,4); tmp = tmp.substring(0,2); System.out.println(tmp); 显然,在本例中,差异可以忽略不计,但当您在数千个字符串/其他对象上执
System.out.println( str.substring(0,4).substring(0,2));
温度变量
String tmp = str.substring(0,4);
tmp = tmp.substring(0,2);
System.out.println(tmp);
显然,在本例中,差异可以忽略不计,但当您在数千个字符串/其他对象上执行此操作时,可能会产生影响
我的问题是,在不进行额外的对象分配或填充堆(从而使GC更快地被调用)方面,其中一个更“有效”吗
我试图在一个循环中比较两个字符串的字节码,但看起来很相似,最后几行是sans。我不理解所有的字节码调用,所以我不确定这些调用是否与分配新对象有关
Compiled from "TestNoTmp.java"
public class TestNoTmp {
public TestNoTmp();
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_4
1: anewarray #2 // class java/lang/String
4: dup
5: iconst_0
6: ldc #3 // String These
8: aastore
9: dup
10: iconst_1
11: ldc #4 // String Are__
13: aastore
14: dup
15: iconst_2
16: ldc #5 // String Some_
18: aastore
19: dup
20: iconst_3
21: ldc #6 // String Strings
23: aastore
24: astore_1
25: aload_1
26: astore_2
27: aload_2
28: arraylength
29: istore_3
30: iconst_0
31: istore 4
33: iload 4
35: iload_3
36: if_icmpge 69
39: aload_2
40: iload 4
42: aaload
43: astore 5
45: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
48: aload 5
50: iconst_0
51: iconst_4
52: invokevirtual #8 // Method java/lang/String.substring:(II)Ljava/lang/String;
55: iconst_0
56: iconst_2
57: invokevirtual #8 // Method java/lang/String.substring:(II)Ljava/lang/String;
60: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
63: iinc 4, 1
66: goto 33
69: return
}
public class TestTmp {
public TestTmp();
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_4
1: anewarray #2 // class java/lang/String
4: dup
5: iconst_0
6: ldc #3 // String These
8: aastore
9: dup
10: iconst_1
11: ldc #4 // String Are__
13: aastore
14: dup
15: iconst_2
16: ldc #5 // String Some_
18: aastore
19: dup
20: iconst_3
21: ldc #6 // String Strings
23: aastore
24: astore_1
25: aload_1
26: astore_2
27: aload_2
28: arraylength
29: istore_3
30: iconst_0
31: istore 4
33: iload 4
35: iload_3
36: if_icmpge 77
39: aload_2
40: iload 4
42: aaload
43: astore 5
45: aload 5
47: iconst_0
48: iconst_4
49: invokevirtual #7 // Method java/lang/String.substring:(II)Ljava/lang/String;
52: astore 6
54: aload 6
56: iconst_0
57: iconst_2
58: invokevirtual #7 // Method java/lang/String.substring:(II)Ljava/lang/String;
61: astore 6
63: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
66: aload 6
68: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
71: iinc 4, 1
74: goto 33
77: return
}
从“TestNoTmp.java”编译而来
公共类TestNoTmp{
公共TestNoTmp();
代码:
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
公共静态void main(java.lang.String[]);
代码:
0:iconst_4
1:anewarray#2//class java/lang/String
4:dup
5:iconst_0
6:ldc#3//将这些
8:aastore
9:dup
10:iconst_1
11:ldc#4//字符串是__
13:aastore
14:dup
15:iconst_2
16:ldc#5//串一些_
18:aastore
19:dup
20:iconst_3
21:ldc#6//字符串
23:aastore
24:astore_1
25:aload_1
26:astore_2
27:aload_2
28:排列长度
29:istore_3
30:iconst_0
31:istore 4
33:iload 4
35:iload_3
36:if_icmpge 69
39:aload_2
40:iload 4
42:aaload
43:astore 5
45:getstatic#7//fieldjava/lang/System.out:Ljava/io/PrintStream;
48:aload 5
50:iconst_0
51:iconst_4
52:invokevirtual#8//方法java/lang/String。子字符串:(II)Ljava/lang/String;
55:iconst_0
56:iconst_2
57:invokevirtual#8//方法java/lang/String。子字符串:(II)Ljava/lang/String;
60:invokevirtual#9//方法java/io/PrintStream.println:(Ljava/lang/String;)V
63:iinc 4,1
66:转到33
69:返回
}
公共类TestTmp{
公共测试tmp();
代码:
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
公共静态void main(java.lang.String[]);
代码:
0:iconst_4
1:anewarray#2//class java/lang/String
4:dup
5:iconst_0
6:ldc#3//将这些
8:aastore
9:dup
10:iconst_1
11:ldc#4//字符串是__
13:aastore
14:dup
15:iconst_2
16:ldc#5//串一些_
18:aastore
19:dup
20:iconst_3
21:ldc#6//字符串
23:aastore
24:astore_1
25:aload_1
26:astore_2
27:aload_2
28:排列长度
29:istore_3
30:iconst_0
31:istore 4
33:iload 4
35:iload_3
36:if_icmpge 77
39:aload_2
40:iload 4
42:aaload
43:astore 5
45:aload 5
47:iconst_0
48:iconst_4
49:invokevirtual#7//方法java/lang/String。子字符串:(II)Ljava/lang/String;
52:astore 6
54:aload 6
56:iconst_0
57:iconst_2
58:invokevirtual#7//方法java/lang/String。子字符串:(II)Ljava/lang/String;
61:astore 6
63:getstatic#8//fieldjava/lang/System.out:Ljava/io/PrintStream;
66:aload 6
68:invokevirtual#9//方法java/io/PrintStream.println:(Ljava/lang/String;)V
71:iinc 4,1
74:转到33
77:返回
}
在您的示例中,您使用的是不可变的字符串。在代码中:
str.substring(0,4).substring(0,2)
第一次调用substring必须生成一个新的String对象,因为str无法修改。类似地,在新字符串对象上对substring的第二次调用将创建另一个新字符串对象
字节码的差异只是编译器调用方法的顺序的结果。在TestTmp情况下,所有字符串操作都发生在调用PrintStream之前。对于TestNoTmp,字符串调用发生在PrintStream调用中,这在查看代码时非常符合逻辑
为了回答您的问题,这对对象分配和GC影响没有影响。这就是您的答案。虽然
javac
没有做太多优化,但这些小事情对生成的字节码没有影响。此外,您可能希望专注于真正的性能瓶颈。即使temp变量确实影响字节码,这也不会是一个。虽然字节码略有不同,所以我不确定这是否会产生影响,或者我的假设是否正确(我可以用一种不会产生影响的方式编写我的示例),这不会产生影响。