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.