Именование двух видов области в Java

у меня есть трудности в названии двух видов областей, которые я вижу в Java:

class Fun {
    int f = 1;
    void fun() {
        int f = 2;
        while(true){
            int f = 3;
            int g = 1;
        }
        int g = 2;
    }
}

дело в основном с f = 3 и g = 2;

A while оператор не вводит новую область, поэтому я не могу создать локальную переменную while с именем f. Но если я создам локальную переменную с именем g затем я могу "воссоздать" его после цикла. Почему? Я знаю, что он больше не доступен, но если компилятор проверяет доступность, то он почти проверяет масштабы..

поэтому мне было интересно, что здесь происходит, как называются эти понятия? Это то же самое, что и в C++?


мне просто удалось установить g++ и попробовать его сам:

#include <iostream>
using namespace std;

int main(){
    int f = 0;
    for(int i=0; i<1; i++){
        int f = 1;
        cout << f << endl;
        {
            int f = 2;
            cout << f << endl;
        }
    }
    cout << f << endl;
}

таким образом, по-видимому, C++ относится ко всем областям одинаково!

4 ответов


как только вы покинули while{} loop g вышел из области видимости, как только вы его покинули. Затем было действительно объявить g снова.

локальные переменные находятся только в области действия на протяжении блока, в котором они объявлены.

подробнее:

  • первый f объем объекта. Его можно получить из объекта вообще раз.
  • второй f локальный масштаб. Вы получаете доступ к нему с помощью f, вы все еще может получить доступ к объект объем f используя this.f.
  • третий f пытается создать вторую локальную область f. Это недопустимо.

  • первый g создает локальную область g.

  • второй g создать вторую локальную область g но первый уже вышел за рамки и исчез.

таким образом, единственным недействительным объявлением является третье f.

там это третий тип области, где объявляются статические переменные-это переменные, которые являются общими для каждого экземпляра класса.

существует несколько имен для типов, некоторые из наиболее распространенных-локальные переменные, переменные экземпляра (также известные как поля) и переменные класса (также известные как статические поля). У вас также есть параметры метода, но это просто другой способ получить локальную переменную.

для дальнейшего чтение:


в java запрещено теневые переменные из внешних локальных областей, IIRC. Это просто "произвольное" правило языка, чтобы предотвратить ошибки программиста. C# имеет такое же правило, IIRC или даже более строгое (последнее g может быть ошибка в C#, потому что она была в области того же метода, не уверен). C и C++ не имеют этого правила, хотя обычно существует предупреждение компилятора, в зависимости от флагов компилятора и предупреждения.

каждый {} новый блок масштаб.

последние g не тень ранее g потому что раньше он больше не находится в области видимости. Так что все в порядке.

внутренний f тени более ранних местных f который все еще находится в области, так что не в порядке.

переменные-члены класса по-прежнему доступны и с помощью this. так что это нормально, чтобы тень их (хотя потенциально вводит в заблуждение, esp. если подсветка синтаксиса в IDE не выделяет их по-разному).


class Fun {
    int f = 1;// Its My f and i wont tell my fun() not to have 'f'
    void fun() {
        int f = 2; //Its my 'f' and till i own my 'f' i wont consider Fun Class 'f' also while 'f' 
        while(true){
            int f = 3; //Its my 'f' and he rules within me alone 
            int g = 1;
        }
        int g = 2;
    }
}

область объявления локальной переменной в блоке-это остальная часть блока, в котором появляется объявление (область объявления JLS 6.3).

void fun() {  // block starts

   int f = 2; // f will be visible everywhere from fun() body

...

   {  // another block starts, it's legal even without while or for
      // f is visible, you cannot declare it again

      int g = 1; // will be visible till the end of the block

   }

   // g is invisible here because the block where it was declared ended
}