2015-06-16 15 views
6

In Java Re-deklarieren, können wir eine Variable nicht in gleichem Umfang mit der anderen Variable deklarieren, die den gleichen Namen hat:Variablen innerhalb von Schleifen in Java

int someInteger = 3; 

... 

int someInteger = 13; 

Syntaxfehler, nicht kompiliert. Wenn wir es jedoch in eine Schleife setzen:

for (int i = 0; i < 10; i++) { 
    int someInteger = 3; 
} 

Erzeugt keinen Fehler, funktioniert sehr gut. Wir deklarieren grundsätzlich die gleiche Variable. Was ist der Grund? Was ist die Logik, die ich dahinter nicht verstehe?

+1

_We erstellen sind basicly die gleiche variable._ erklärt Sind Sie? Wie können Sie auf den vorherigen Wert zugreifen? –

+2

Müllsammlung. Variablen in den Schleifen sind nicht mehr im Bereich, wie das Programm ausführt. –

+1

@MalikBrahimi: Es ist wahr, dass Variablen innerhalb der Schleife nicht mehr im Bereich außerhalb der Schleife sind, aber der Grund ist * nicht * "Garbage Collection". Müllsammlung bezieht sich auf die Entsorgung von Objekten, die mit "neu" belegt sind. –

Antwort

8

Denken Sie so, nach jeder Schleife wird der Bereich "zerstört" und die Variable ist weg. In der nächsten Schleife wird ein neuer Bereich erstellt, und die Variable kann erneut in diesem Bereich deklariert werden.

Sie können dies auch tun, für die ähnlichen Grund

 { 
      int someInteger = 3; 
     } 
     { 
      int someInteger = 13; 
     } 

By the way, Java erlaubt keine lokale Variable Abschattung, die

unbequem sein könnte
 int x = 3; 
     { 
      int x = 13; // error! 
     } 

     Consumer<Integer> consumer = (x)->print(x); // ERROR! 
     // lambda parameter is treated like local variable 

     Runnable r =()->{ int x; ... } // ERROR 
     // lambda body is treated like local block 
4

Java hat, was "genannt wird block scoping ', das heißt, welcher Code (definiert durch die umschließenden geschweiften Klammern), in dem eine Variable deklariert ist, die (und nur dort) ist, wo sie existiert. Es bedeutet auch, dass jede Variable nur einmal in einem bestimmten Block deklariert werden kann.

Wenn Sie sagen,

for (int i = 0; i < 10; i++) { 
    int someInteger = 3; 
} 

Ein neuer Block bei jeder Iteration erzeugt wird. Es ist ähnlich

{ 
    int someInteger = 3; 
} 
{ 
    int someInteger = 3; 
} 
... 

In diesem Fall gibt es nur 1 Variable someInteger in jedem Block zu sagen, benannt ist.

Wenn Sie sagen,

{ 
    int someInteger = 3; 
    ... 
    int someInteger = 3; 
} 

Der Compiler beschwert sich richtig, dass Sie im selben Block (oder Umfang) mehr als eine Variable mit demselben Namen deklarieren des Codes.

-1

Verschiedene Bereiche;

int variables = 3; 
.... 
int variables = 13; 

Scope einstimmig, sicherlich kompilieren Fehler; Aber

for (;;;) { 
     int variables = 13; 
} 

Jeder Zyklus entspricht die Variablen Variablen Variablen, bevor mit der Änderung des Umfangs wieder herzustellen verschwinden; JVM-Stack-Frame ist ein solcher Mechanismus (lokale Variablen mit dem Beginn der Zuweisung, mit dem Ende des Prozesses und Beseitigung);

2

Im Rahmen eines Blocks, wird eine neue someInteger erstellt und es Schatten der lexikalischen Umfang von anyother someInteger.Die Wikipedia Eintrag der Variable shadowing sagt, (teilweise)

variable Abschattung tritt auf, wenn eine Variable in einem gewissen Umfang (Entscheidungsblock, Methode oder innere Klasse) erklärt hat die gleichen Namen wie eine Variable in einem äußeren erklärt Umfang. Auf der Ebene der Bezeichner (Namen statt Variablen) ist dies als name masking bekannt.

0

Sie können den gleichen Variablennamen innerhalb einer Klasse oder Methode wiederverwenden, wenn sie sich in einem anderen Bereich als der erste befindet.

In Ihrem ersten Beispiel haben die beiden Variablen den gleichen Gültigkeitsbereich und daher kommt es zu einem Namenskonflikt und der Compiler meldet einen Fehler. In Ihrem zweiten Beispiel haben sie einen anderen Gültigkeitsbereich - einer befindet sich in der Methode, der andere innerhalb der for-Schleife - daher gibt es keinen Konflikt und der Code wird kompiliert.

2

Alle Variablen haben einen Gültigkeitsbereich. Ein Bereich ist in einer Klammer {} verschachtelt. Wenn Sie diesen Geltungsbereich verlassen, ist dieser Kontext nicht mehr vorhanden, sodass Sie andere Variablen mit demselben Namen definieren können. Andernfalls können Sie nicht.

Ich gebe Ihnen zwei Beispiele:

// define new scope named "methodA" 
public void methodA() { 
    int a = 3; 
    // define new scope named "loop" 
    for (int i = 0; i < 10; i++) { 
     int a = 6; // ERROR 
    } 
} 

In obigen Fall Sie Fehler treffen. Da der Bereich "loop" innerhalb des Bereichs "methodA" liegt, existiert die erste Definition von "noch", wenn Sie zum Bereich "loop" wechseln.

Zweiter Fall:

// define new scope named "methodA" 
public void methodA() { 
    // define new scope inside methodA scope 
    { 
     int a = 3; 
    } 
    // define new scope named "loop" 
    for (int i = 0; i < 10; i++) { 
     int a = 6; // NO ERROR 
    } 
} 

obigen Code erfolgreich kompiliert werden, da erste Definition eines in unterschiedlichen Rahmen der zweiten Definition von a, und diese Bereiche nicht verschachtelt.

+0

true - eine lokale Variable kann nicht beschattet werden. – ZhongYu

+0

kann von lokaler/anonymer Klasse zwar beschattet werden, aber nicht von Lambda – ZhongYu

-1

Sie können Ihre Variable in ein Array schieben.

Stack myarr = new Stack(); 
for (int i = 0; i < 10; i++) { 
    int someInteger = 3; 
myarr.push(someInteger); 
} 

oder eine Variable everyloop

for (int i = 0; i < 10; i++) { 
    int someInteger+i = 3; 
} 
Verwandte Themen