Java: new Something (). Method () vs temporary variable

maybe he is dumb, but is there any difference between

new Something().method();

      

and

Something tmpSomething = new Something();
tmpSomething.method(); 

      

since I was only calling one method on that specific object, I chose the first solution, but I'm not sure if this is exactly the same behavior ...

I just want to mention that the constructor initializes the Writer and the method writes in this file ...

+1


a source to share


8 answers


I did a quick test. This is extremely trivial test code:

public class TestLiveness
{
    public static void test1()
    {
        System.out.println(new Square(4).square());
        count();
    }

    public static void test2()
    {
        Square t = new Square(4);
        System.out.println(t.square());
        count();
    }

    private static void count()
    {
        for(int i=0; i<1000000; i++)
            System.out.println(i);
    }

    static class Square
    {
        private int val;

        Square(int val)
        {
            this.val = val;
        }

        int square()
        {
            return val * val;
        }
    }
}

      



The Javap shows that the two methods are compiled differently; the chain does not touch the local variable table, whereas the temporary variable does indeed remain valid until the method returns. However, the VM / JIT compiler can still perform liveness analysis and allow the instance to be garbage collected before the method returns.

public static void test1();
  Code:
   0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   new     #3; //class TestLiveness$Square
   6:   dup
   7:   iconst_4
   8:   invokespecial   #4; //Method TestLiveness$Square."<init>":(I)V
   11:  invokevirtual   #5; //Method TestLiveness$Square.square:()I
   14:  invokevirtual   #6; //Method java/io/PrintStream.println:(I)V
   17:  invokestatic    #7; //Method count:()V
   20:  return

public static void test2();
  Code:
   0:   new     #3; //class TestLiveness$Square
   3:   dup
   4:   iconst_4
   5:   invokespecial   #4; //Method TestLiveness$Square."<init>":(I)V
   8:   astore_0
   9:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   12:  aload_0
   13:  invokevirtual   #5; //Method TestLiveness$Square.square:()I
   16:  invokevirtual   #6; //Method java/io/PrintStream.println:(I)V
   19:  invokestatic    #7; //Method count:()V
   22:  return

      

+4


a source


There is no difference other than that in the second case you have an unnecessary variable lying around, making it difficult to work with the code.



Also, objects that are created only to be discarded after a single method call is a code smell .

+3


a source


They are the same. Although constructing an object and calling only one method on it can indicate bad design. Why not allow the Something.method();

constructor to be expanded unnecessarily?

+2


a source


Okay, in the second case, you have a tmpSomething object so you can use it everywhere in your code, but in the first example, you don't. You cannot do that.

My guess is that the first method is probably more efficient, but probably not the best practice for Java conventions.

+1


a source


If you can get some value from the first call, you might want to define your static method:

public static ____ method() {
}

      

+1


a source


There is a subtle difference between the two fragments, but only when viewed within their scope. Let's consider them in terms of methods:

  public void doSomething1() {
    new Something().method();
    doSomeLongRunningSomething();   
  }

  public void doSomething2() {
    Something tmpSomething = new Something();
    tmpSomething.method();
    doSomeLongRunningSomething();   
  }

      

In the first method, "something" is immediately available for garbage collection, and in the second method, it tmpSomething

remains within scope at runtime doSomeLongRunningSomething

. Doing something interesting during the time finalize

(like closing a file) can lead to some quirks.

However, my preference is for the second example and the name of the new instance as it helps in debugging processing. As you step through the code, you have a named instance that's easier to look at. This does not apply when you get pre-existing instances, in which case I find the chaining methods more readable, eg. myDog.getEyes().getLeftEye().getColorAsRgb().getRed()

...

+1


a source


First, I agree with everyone and say that they are the same in terms of function.

However, I am of the opposite opinion of what most of them say in this post, and this is what I believe the first example is the way to go.

And with the first example, I would expand it even further with some form of dependency injection. This will get you in the habit of giving you the ability to test things out if you need to introduce a mock / test version of that "Something" class.

Also, not damaging trains (doing more than one operation on the same line that is code smell like new dog (). GetEyes (). GetColour ();) improves readability in my opinion, and also optimizes your ability to refactor later ... Just because at the moment you are only calling that one method on that object does not mean that you don't need that object to do something else on it later, which means that you will have to retrieve the variable for that object "What something "anyway.

0


a source


There is nothing wrong with that, even if you only call one function.

See Free Interfaces on Wikipedia or Free Interfaces by Martin Fowler

0


a source







All Articles