views:

138

answers:

7

I'm curious to know if either of these two Java method invocations will behave differently at all in terms of processor time, memory allocation and/or garbage collection.

SomeObject myObj = new SomeObject();
myObj.doSomething();

vs.

new SomeObject().doSomething();
+2  A: 

No.    

unbeli
Ha - I was expecting this one.
iandisme
+1  A: 

Assuming that myObj doesn't get used for anything else, as I would infer from the nature of your question, you should see no difference. Either way, the only time you should worry about overhead like this would be if this code is in some loop that is executing it over and over, ad nauseum. If that is the case, Java's JIT optimization should take very good care of you and you should see no difference. I prefer to see this code written the way your second example is, but that's just me.

I instead prefer variant 1 because it makes debugging easier. There is one method call in each line, so you can decide for each method whether you want to step into it or skip it. That way, you can also examine the intermediate results of the algorithms to check whether they have the expected value. That's especially important when calling the methods produces unwanted side effects.
Roland Illig
A: 

The only difference between the two is that as long as the myObj reference is not cleared and part of an object which has a path to root the allocated object will not be garbage collected.

rsp
+4  A: 

The difference is exactly 2 JVM bytecodes, which translates to 1 extra machine instruction, which the JIT may optimize away (if you don't do anything else with the variable).

Tassos Bassoukos
If it was a sensible thing to consider, a naive translation to machine code would typically introduce two instruction (store to local frame, followed by load of the same) - same as the bytecodes.
Tom Hawtin - tackline
Nop, the compiler can reuse the value immediately, either in a register or on the stack (ignoring volatile vars for the moment). javac will put 2 instructions (one store, one load) due to semantics.
Tassos Bassoukos
+1  A: 

While the generated bytecode may be different, I think that this should be one of the easier things for a jit-compiler to optimize. Depending on what it actually does, even the object creation could be optimized away altogether.

Mattias Nilsson
+5  A: 

Looking at the generated bytecode:

// code 1
new SomeObject().doSomething();

// bytecode 1
   0:   new #2; //class SomeObject
   3:   dup
   4:   invokespecial   #3; //Method SomeObject."<init>":()V
   7:   invokevirtual   #4; //Method SomeObject.doSomething:()V
   10:  return

You can clearly see that this one has two more instructions:

// code 2
SomeObject myObj = new SomeObject();
myObj.doSomething();

// bytecode 2
   0:   new #2; //class SomeObject
   3:   dup
   4:   invokespecial   #3; //Method SomeObject."<init>":()V
   7:   astore_1
   8:   aload_1
   9:   invokevirtual   #4; //Method SomeObject.doSomething:()V
   12:  return

Those instructions seem very redundant and easy to optimize-out. I'd bet the JIT compiler would handle them if needed.

Rekin
This is about along the lines of what I expected. Thanks for being less lazy than me and posting the byte code!
iandisme
A: 

The first example will be slightly less efficient. In the first example, the object reference will be held until the end of the function or enclosing block. In the second example, the object reference will be available for garbage collection once the call is complete. Of course, it may not actually be garbage collected.

I haven't checked the generated bytecode. There's probably a difference in how Java holds the reference, but in either case I suspect it's trivial.

Jay