Назначение не возвращает недействительным - PullRequest
0 голосов
/ 01 октября 2018

Я нашел этот фрагмент кода в Google Guava Github , и я не могу понять, почему в 5-й строке метод rowMap не возвращает void, если выполняется условие:

private transient @MonotonicNonNull Map<R, Map<C, V>> rowMap;

public Map<R, Map<C, V>> rowMap() {
  Map<R, Map<C, V>> result = rowMap;
  return (result == null) ? rowMap = createRowMap() : result;
}

Map<R, Map<C, V>> createRowMap() {
  return new RowMap();
}

Разве эта строка не будет эквивалентна:

if (result == null) {
  return rowMap = createRowMap();
} else {
  return result;
}

И тогда присвоение rowMap вернет void.Что я пропустил?

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Результат вычисления выражения присваивания varibale = value равен value, попробуйте:

int a;
System.out.println(a = 1); // 1

Таким образом, он равен:

if (result == null) {
    rowMap = createRowMap();
    return rowMap;
}

См. Jls для получения дополнительной информации:

Когда выражение в программе оценивается (выполняется), результат обозначает одну из трех вещей:

  • Переменная (§4.12) (в C это будет называться lvalue)

  • Значение (§4.2, §4.3)

  • Ничего (выражение называетсябыть недействительным)

...

Выражение ничего не обозначает тогда и только тогда, когда это вызов метода (§15.12), который вызываетметод, который не возвращает значение, то есть метод, объявленный как void (§8.4).

0 голосов
/ 01 октября 2018

Что я пропустил?

Тот факт, что результатом выражения присваивания является значение, которое было присвоено.:-) Таким образом, в этом коде результат вызова createRowMap присваивается rowMap , а возвращается как результат функции rowMap.Это как:

a = b = 42;

... устанавливает b на 42, а затем устанавливает a на 42 (результат присваивания b = 42).

Эффект такой же, как если бы код был написан так:

public Map<R, Map<C, V>> rowMap() {
  Map<R, Map<C, V>> result = rowMap;
  if (result != null) {
    return result;
  }
  rowMap = createRowMap();
  return rowMap;
}
...