2013-06-15 9 views
5

Hinweis: Ich bin mir bewusst, dass die Initialisierung das Problem behebt; Ich nahm einfach an, dass der Compiler dem Ausführungspfad folgen würde und sah, dass foo tatsächlich an dem Punkt initialisiert wurde, an dem es andeutete, dass es nicht sein könnte.Unerwartete Verhalten mit Java-Initialisierung

Meine ursprüngliche Annahme wäre, dass, wenn die Länge nie über 3 war, ich nie Speicher für die Verwendung reservieren müsste.

Das wird nie in der Produktion eingesetzt werden, bin ich einfach nur neugierig

das folgende Beispiel zeigt: -

List<String> foo; 

int length = 5; 

if (length > 3) 
{ 
    foo = new ArrayList<String>(); 
} 

if (length > 4) 
{ 
    foo.add("bar"); 
} 

Warum dies angezeigt, die folgenden werden verursacht?

Die lokale Variable foo nicht

initialisiert wurden

Sicherlich die Zweige folgen, gibt es nie einen Fall, wobei foo nicht initialisiert wird. Ich weiß, dass, wenn ich tun waren: -

List<String> foo = null; 

gäbe es keine Kompilierung Probleme sein, aber warum muss ich das tun?

+2

@Down Voter, könnten Sie zumindest einen Grund angeben? – chrisw

Antwort

5

Lokale Variablen müssen initialisiert werden, bevor sie irgendwo anders verwendet werden, weil sie nicht standardmäßig initialisiert werden. Was ist, wenn if() nicht true ist?

if (length > 3) 
{ 
    foo = new ArrayList<String>(); 
} 

Der Compiler kann nicht feststellen, ob die Bedingung wahr ist.

Eine lokale Variable (§14.4, §14.13) muß explizit ein Wert gegeben werden, bevor sie verwendet wird, entweder durch Initialisierung (§14.4) oder Zuweisung (§15.26), in einer Weise, die durch überprüft werden kann, der Compiler der Regeln für die eindeutige Zuordnung

wie @jlordo wies darauf hin, so dass die length als final die Kompilierung Fehler beheben zu verwenden, da bei der Kompilierung selbst der Compiler weiß, dass der Wert von length immer 5 sein wird und daher die Bedingung length>3 i s immer true, damit die lokale Variable initialisiert wird.

+1

+1 Dies ist der Punkt - "auf eine Weise, die vom Compiler verifiziert werden kann". Der Compiler könnte prinzipiell sagen, dass foo immer zugewiesen wird, bevor es hier verwendet wird, aber nicht. –

+0

+1 Dieses Zitat klärt sicherlich, warum der Fehler zusammen mit Ihrer Erklärung auftritt – chrisw

5

Der Compiler kann nicht sicher sein, dass Sie der Erste sind, wenn der Block eingegeben wird. Wenn dies nicht der Fall ist, bleibt foo nicht initialisiert. Sie können add nicht auf einer nicht initialisierten Variablen aufrufen. Sie können dem Compiler helfen, indem Sie length final machen. Der Compiler wird dann wissen, dass der erste if Block ausgeführt wird.

final int length = 5; 
+0

@ ÓscarLópez: OPs-Code kopieren, 'Länge' final machen und der Compiler-Fehler verschwindet;) – jlordo

+1

@Oscar, final erlaubt es, den Code ohne Fehler zu kompilieren; ob dies das Richtige ist oder nicht, wäre für eine andere Diskussion – chrisw

+0

@ chrisw69: Genau. Ich sage nur, dass dies den Compilerfehler entfernen wird. Ich sage nicht, dass es ein guter Stil ist. – jlordo

1

Dies geschieht, weil foo in einer Verzweigung initialisiert wird. Daher ist der Compiler nicht sicher, ob foo initialisiert wird oder nicht.

2

Da eine lokale Instanz nicht im Gegensatz zu Klassen- oder Objektinstanzen standardmäßig initialisiert wird.

Vom Java Language Specification:

Eine lokale Variable (§14.4, §14.14) müssen explizit einen Wert angegeben werden, bevor sie verwendet wird, entweder durch Initialisierung (§14.4) oder Zuweisung (§15.26), in einer Weise, dies kann vom Compiler anhand der Regeln für die eindeutige Zuordnung (§16) überprüft werden.

Die Standardwerte:

For type byte, the default value is zero, that is, the value of (byte)0. 
For type short, the default value is zero, that is, the value of (short)0. 
For type int, the default value is zero, that is, 0. 
For type long, the default value is zero, that is, 0L. 
For type float, the default value is positive zero, that is, 0.0f. 
For type double, the default value is positive zero, that is, 0.0d. 
For type char, the default value is the null character, that is, '\u0000'. 
For type boolean, the default value is false. 
For all reference types (§4.3), the default value is null. 
1

Instanz und Klassenvariablen werden initialisiert oder 0-Werte auf null. Aber lokale Variablen sind nicht. Daher müssen Sie die lokalen Variablen vor der Verwendung initialisieren.

Verwandte Themen