哪一个更优或者有什么不同?
String s = methodThatReturnsString();
int i = methodThatReturnsInt();
thirdMethod(s, i);
Run Code Online (Sandbox Code Playgroud)
要么
thirdMethod(methodThatReturnsString(), methodThatReturnsInt());
Run Code Online (Sandbox Code Playgroud)
通过最优,我的意思是在内存使用等方面最优.
Ada*_*ter 10
我非常怀疑这两种形式都是相同的,但不要相信我的意思.让我们发现自己!:d
public class Tests {
public void test1() {
String s = methodThatReturnsString();
int i = methodThatReturnsInt();
thirdMethod(s, i);
}
public void test2() {
thirdMethod(methodThatReturnsString(), methodThatReturnsInt());
}
public String methodThatReturnsString() {
return "";
}
public int methodThatReturnsInt() {
return 0;
}
public void thirdMethod(String s, int i) {
}
}
Run Code Online (Sandbox Code Playgroud)
我们来编译它:
> javac -version javac 1.6.0_17 > javac Tests.java
现在,让我们打印出字节码指令!
> javap -c Tests
Compiled from "Tests.java"
public class Tests extends java.lang.Object{
public Tests();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return
public void test1();
Code:
0: aload_0
1: invokevirtual #2; //Method methodThatReturnsString:()Ljava/lang/String;
4: astore_1
5: aload_0
6: invokevirtual #3; //Method methodThatReturnsInt:()I
9: istore_2
10: aload_0
11: aload_1
12: iload_2
13: invokevirtual #4; //Method thirdMethod:(Ljava/lang/String;I)V
16: return
public void test2();
Code:
0: aload_0
1: aload_0
2: invokevirtual #2; //Method methodThatReturnsString:()Ljava/lang/String;
5: aload_0
6: invokevirtual #3; //Method methodThatReturnsInt:()I
9: invokevirtual #4; //Method thirdMethod:(Ljava/lang/String;I)V
12: return
public java.lang.String methodThatReturnsString();
Code:
0: ldc #5; //String
2: areturn
public int methodThatReturnsInt();
Code:
0: iconst_0
1: ireturn
public void thirdMethod(java.lang.String, int);
Code:
0: return
}
我觉得这看起来有点奇怪 - test1()而且test2()有所不同.看起来编译器正在添加调试符号.也许这迫使它明确地将返回值分配给局部变量,引入了额外的指令.
让我们尝试重新编译它而不需要调试:
> javac -g:none Tests.java
> javap -c Tests
public class Tests extends java.lang.Object{
public Tests();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return
public void test1();
Code:
0: aload_0
1: invokevirtual #2; //Method methodThatReturnsString:()Ljava/lang/String;
4: astore_1
5: aload_0
6: invokevirtual #3; //Method methodThatReturnsInt:()I
9: istore_2
10: aload_0
11: aload_1
12: iload_2
13: invokevirtual #4; //Method thirdMethod:(Ljava/lang/String;I)V
16: return
public void test2();
Code:
0: aload_0
1: aload_0
2: invokevirtual #2; //Method methodThatReturnsString:()Ljava/lang/String;
5: aload_0
6: invokevirtual #3; //Method methodThatReturnsInt:()I
9: invokevirtual #4; //Method thirdMethod:(Ljava/lang/String;I)V
12: return
public java.lang.String methodThatReturnsString();
Code:
0: ldc #5; //String
2: areturn
public int methodThatReturnsInt();
Code:
0: iconst_0
1: ireturn
public void thirdMethod(java.lang.String, int);
Code:
0: return
}
不可思议!
因此,根据我的编译器(Sun JDK),第二个版本的字节码更短.但是,虚拟机可能会优化任何差异.:)
编辑:一些额外的澄清礼貌Joachim Sauer的评论:
重要的是要注意字节代码只讲述故事的一半:它实际执行的方式在很大程度上取决于JVM(这与C/C++完全不同,在C/C++中你可以看到汇编程序代码,它正是它的执行方式).我认为你意识到这一点,但我认为应该在帖子中更清楚.