I highly suspect that both forms are identical, but don't take my word for it. Let's find out ourselves! :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) {
}
}
Let's compile it:
> javac -version
javac 1.6.0_17
> javac Tests.java
Now, let's print out the bytecode instructions!
> 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
}
I thought this looked a bit strange - test1()
and test2()
are different. It looks like the compiler is adding the debugging symbols. Perhaps this is forcing it to explicitly assign return values to the local variables, introducing extra instructions.
Let's try recompiling it with no debugging:
> 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
}
Inconceivable!
So, according to my compiler (Sun JDK), the bytecode is shorter for the second version. However, the virtual machine will probably optimize any differences away. :)
Edit: Some extra clarification courtesy of Joachim Sauer's comment:
It's important to note that the byte
code tells only half the story: How it
is actually executed depends a lot on
the JVM (that's quite different to
C/C++, where you can see the assembler
code and it's exactly how it's
executed). I think you realize that,
but I think it should be made clearer
in the post.