В чем разница между «return new A()» и «return a = new A()»

#java

#java

Вопрос:

Я видел, что во многих библиотеках при возврате некоторого результата используется return a = new A() (например return entrySet = new EntrySet() ) вместо возврата just new EntrySet() , в чем разница ?

Комментарии:

1. Какая область имеет a или newEntrySet имеет?

2. Если entrySet является локальным, то разницы нет. Если entrySet является членом класса, то есть явная разница.

Ответ №1:

Последний присваивает значение a перед возвратом.

Если a это локальная переменная, это почти наверняка не имеет значения. Если a это переменная экземпляра (или статическая), это будет иметь видимый побочный эффект. Иногда он используется для какой-то ленивой инициализации, например

 private String foo;

public String getFoo()
{
    if (foo != null)
    {
        return foo;
    }
    return foo = computeFoo();
}

private String computeFoo() { .. }
  

Комментарии:

1. Вопрос касается Java, а не C #.

2. Только Джон Скит может отвечать на вопросы с неправильным языком и при этом набирать большинство голосов 🙂

3. @JBNizet: Упс, исправлено, спасибо. Точно такой же принцип, конечно 🙂

4. @aioobe: это то, что сказал бы заговорщик 😉

Ответ №2:

return a = new A() возвращает значение присваивания new A() to a . Значение присваивания — это значение, которое было присвоено.

Таким образом, они оба возвращают одно и то же значение.

также return a = new A() , однако, присваивает значение a . Если a это локальная переменная, то это присваивание, которое не будет иметь никакого эффекта и должно быть удалено. Если a это поле, то это может быть использовано для запоминания последнего возвращаемого значения по какой-то причине.

В последнем случае это будет работать, но я бы сказал, что это плохой стиль (эта строка делает больше, чем 1 вещь. На самом деле это делает 3 вещи), и я бы переписал это так:

 a = new A();
return a;
  

Ответ №3:

Первое, что приходит на ум, это «чтобы вы могли проверить возвращаемое значение внутри вызываемого метода, прежде чем фактически выйти из него». Честно говоря, я всегда думал, что оба способа эквивалентны.

Ответ №4:

Если это локальная переменная, разницы вообще нет (даже после тривиальной оптимизации). Это просто бессмысленное назначение. Но если это присвоение полю, это просто сокращение для:

 this.a = new A();
return this.a;
  

Некоторым людям нравится делать это одним способом, некоторым другим.

Ответ №5:

Результатом присваивания является присваиваемое значение.

Итак, в

  private int x;

 public int setX(int x) { return this.x = x; }
  

setX метод присваивает свой аргумент this.x и возвращает новое значение this.x .

Ответ №6:

Разница в том, что значение сначала присваивается переменной, а затем возвращается. Если это локальная переменная, это на самом деле не имеет никакого эффекта, поскольку она будет вне области видимости, как только метод вернется. Было бы важно, является ли это переменной экземпляра.

Но я никогда не видел такого рода вещей и считал бы это довольно сомнительной практикой. В чем именно состоят «библиотеки mnay», в которых вы видели, как они используются?

Обновление: я только что видел, как он использовался java.util.HashMap , по-видимому, для отложенной инициализации entrySet поля. Я думаю, это имеет смысл для такого рода вещей.

Комментарии:

1. например, EnumMap в библиотеках Java core существует набор временных полей entrySet, который обновляется каждый раз, когда возвращается набор записей.

2. @Bax: На самом деле, это то же самое, отложенная инициализация. Если поле не равно null, его содержимое возвращается напрямую.