Какая переменная упоминается здесь? - PullRequest
0 голосов
/ 21 сентября 2018
class Test {
  int a;

  void method() {
    a = 1;
    int a = a = 2;
    a = 3;
  }
}

В method есть много a с.На что они все ссылаются?

1 Ответ

0 голосов
/ 21 сентября 2018

Это простой пример причудливости правил определения области действия Java.

a = 1;
int a = a = 2;
a = 3;

Разбивая его построчно:

  • a = 1; относится кпеременная-член.
  • a = 3; ссылается на локальную переменную, потому что это после объявления локальной переменной.Довольно странно, что вы можете ссылаться на два разных символа через один и тот же идентификатор в одном и том же методе.
  • int a = a = 2;: вторая a - это локальная переменная .

Самостоятельная ссылка в объявлении переменной действительно любопытна.Вы можете найти это в спецификации языка :

  • Область объявления локальной переменной в блоке (§14.4) - остальная часть блока, в которомпоявляется объявление , начинающееся со своего собственного инициализатора и включающее любые дальнейшие деклараторы справа в оператор объявления локальной переменной.

Также верно, что переменные-члены могут ссылатьсясамим себе в своем инициализаторе;но это по несколько другой причине:

  • Область объявления члена m, объявленного или унаследованного классом типа C (§8.1.6), представляет собой весь текстC, включая любые объявления вложенных типов.

Мне еще предстоит найти убедительную причину существования этого правила для локальных переменных;может быть, вы просто действительно очень хотите убедиться, что он назначен.Единственное, что я могу себе позволить, это использовать переменную в качестве временного хранилища при оценке инициализатора, например:

int a = method(a = somethingThatIsReallyExpensiveToCompute(), a);

будет эквивалентно:

int a;
{
  int tmp = somethingThatIsReallyExpensiveToCompute();
  a = method(tmp, tmp);
}

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

...