Java: новый Something (). Method () против временной переменной - PullRequest
1 голос
/ 26 мая 2009

возможно, это глупо, но есть ли разница между

new Something().method();

и

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

поскольку я вызывал только один метод для этого конкретного объекта, я выбрал первое решение, но я не уверен, что это точно такое же поведение ...

Я просто хочу упомянуть, что конструктор инициализирует Writer и метод записи в этом файле ...

Ответы [ 8 ]

4 голосов
/ 26 мая 2009

Я сделал быстрый тест. Это очень простой тестовый код:

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;
        }
    }
}

Javap показывает, что два метода скомпилированы по-разному; сцепление не касается таблицы локальных переменных, тогда как временная переменная действительно остается до тех пор, пока метод не вернется. Однако компилятор VM / JIT может по-прежнему выполнять анализ живучести и разрешать сборку экземпляра до возврата метода.

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
3 голосов
/ 26 мая 2009

Нет никакой разницы, за исключением того, что во втором случае у вас есть ненужная переменная, которая затрудняет поддержку кода.

Кроме того, объекты, которые создаются только для удаления после вызова одного метода, представляют собой запах кода .

2 голосов
/ 26 мая 2009

Они одинаковы. Хотя создание объекта и вызов только одного метода может указывать на плохой дизайн. Почему бы не разрешить Something.method(); без необходимости выставлять конструктор?

1 голос
/ 26 мая 2009

Существует небольшая разница между двумя фрагментами, но только если смотреть в их пределах. Рассмотрим их в рамках методов:

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

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

В первом методе «что-то» сразу доступно для сборки мусора, тогда как во втором методе tmpSomething остается в области видимости во время выполнения doSomeLongRunningSomething. Если вы делаете что-нибудь интересное во время finalize (например, закрытие файла), это может ввести некоторые причуды.

Тем не менее, я предпочитаю второй пример и присваивать имя новому экземпляру, поскольку он помогает в обработке отладки. При пошаговом выполнении кода у вас есть именованный экземпляр, который легче наблюдать. Это неприменимо, когда вы получаете уже существующие экземпляры, и в этом случае я нахожу методы цепочки более читабельными, например, myDog.getEyes().getLeftEye().getColorAsRgb().getRed().

1 голос
/ 26 мая 2009

Если вы можете получить какое-то значение из первого вызова, возможно, вы захотите определить статический метод:

public static ____ method() {
}
1 голос
/ 26 мая 2009

Ну, во втором случае у вас есть объект tmpSomething, так что вы можете использовать его повсюду в коде, но в первом примере это не так. Так что ты не можешь.

Я думаю, что первый метод, вероятно, более эффективен на ощупь, но, вероятно, не лучший метод для соглашений Java.

0 голосов
/ 26 мая 2009

В этом нет ничего плохого, даже если вы вызываете только одну функцию.

Взгляните на Свободные интерфейсы в Википедии или Свободные интерфейсы . Автор Martin Fowler

0 голосов
/ 26 мая 2009

Во-первых, я согласен со всеми и скажу, что они одинаковы по функциям.

Тем не менее, я придерживаюсь противоположного мнения о том, что большинство говорят в этом посте, а именно: я думаю, что первый пример - это путь.

И в первом примере я бы расширил его еще с помощью некоторой формы внедрения зависимости. Это даст вам привычку давать вам возможность тестировать вещи, если вам нужно внедрить пробную / тестовую версию этого класса «Нечто».

Кроме того, не нарушая поезда (выполнение более одной операции в одной строке, которая является запахом кода, например, new dog (). GetEyes (). GetColour ();), по моему мнению, улучшает читаемость, а также оптимизирует возможность рефакторинга позже. То, что в данный момент вы вызываете только один метод для этого объекта, не означает, что вам не понадобится этот объект для того, чтобы потом что-то делать с ним, а значит, вам все равно придется извлекать переменную для этого объекта Something.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...