2010-11-04 20 views
12

In vielen Beispielen Code sehe ich Variablen mit Null-Werte und später zugeordnet sinnvollere Werte.Warum Variablen mit einem Null-Wert instanziieren

Ich habe mich nur gefragt, warum Leute das tun können. Ich vermute, Try-Catch-Blöcke können dazu kommen, aber ich sehe auch Variablen instanziiert Nullwerte innerhalb eines Try Block.

(Ich bin sicher, dass dies eine ziemlich sprachunabhängig Frage, aber ich programmiere fast vollständig in Java nur als Referenz)

Alle Erkenntnisse zu schätzen!

+3

Ich denke, das ist eine gültige Frage. +1 um den Downvote auszugleichen. –

+0

Das passiert, wenn der Downvoter keinen Kommentar hinterlässt. –

+0

Einfach weil in vielen Fällen sonst der Code einfach nicht kompiliert wird. Nun, warum die Java-Spezifikationen dies vorschreiben, ist eine andere Frage als +1 an MForster, die auf die genaue Compiler-Fehlermeldung hingewiesen hat. Beachten Sie, dass Sie nicht einmal eine gültige * .java * -Datei kompilieren müssen, um diese Fehlermeldung zu erhalten. Zum Beispiel: IntelliJ IDEA (erstaunliche Java-IDE) warnt Sie in Echtzeit vor Ihrem ** Fehler **, sogar bei einer partiellen AST (das heißt: einer partiellen .java-Datei, die Sie selbst nicht kompilieren konnten, weil sie unvollständig ist). – SyntaxT3rr0r

Antwort

13

Der Java-Compiler erkennt in bestimmten Fällen, ob eine Variable nicht in allen möglichen Kontrollflüssen initialisiert wurde und gibt einen Fehler aus. Um diese Fehlermeldungen zu vermeiden, muss die Variable explizit initialisiert werden.

Zum Beispiel in diesem Fall:

public Integer foo() { 
    Integer result; 

    if (Math.random() < 0.5) { 
     result = 1; 
    } 

    return result; 
    } 

Der Compiler würde diese Fehlermeldung geben: „Das lokale Variable Ergebnis kann nicht initialisiert wurde“. Hier

ist, was die Java Language Specification sagt:

Jede lokale Variable (§14.4) und jede leere final (§4.5.4) Feld (§8.3.1.2) muss auf jeden Fall zugewiesenen Wert haben, wenn Jeder Zugriff auf seinen Wert erfolgt. Ein Java-Compiler muss eine bestimmte konservative Flow-Analyse ausführen, um sicherzustellen, dass für jeden Zugriff einer lokalen Variablen oder leeren Endfeld f, f eindeutig vor dem Zugriff zugewiesen ist; Andernfalls muss ein Kompilierzeitfehler von auftreten.

Beachten Sie, dass (im Gegensatz zu den Feldern!) Lokale Variablen werden nicht automatisch auf null initialisiert.

+0

Es wird ein Fehler ausgegeben, um Laufzeitfehler zu vermeiden! Ich würde nicht sagen, dass es notwendig ist. Tatsächlich würde ich sagen, dass es sehr schlecht ist, nicht sicherzustellen, dass jeder Kontrollfluss ein gültiges Objekt hat. – wheaties

+0

Ich bezog mich auf die Fehlermeldung vom Compiler. Ich denke, diese sind sogar von der Sprachspezifikation vorgeschrieben. – MForster

+12

Glaubt irgendjemand, dass es seltsam ist, dass QuakerOat diese Frage gestellt hat, und Wheaties kommentierten eine Antwort? –

4

Persönlich mag ich es nicht für Mitgliedsfelder, die einen Wert im Konstruktor nehmen. Es gab eine Zeit, als ich dachte, es wäre einfach schön, explizit zu sein, aber es gibt tatsächlich einen Bytecode-Unterschied zwischen der expliziten Zuweisung eines Feldes zu null oder dem Feld, das den Standardwert annimmt.

Auch für Felder, die als Null beginnen (und dann irgendwann nach der Initialisierung einen Wert erhalten), bin ich kein großer Fan von ihnen. Es hebt normalerweise nur Missverständnisse von dem Entwickler hervor, der das getan hat.

Die try-catch Relevanz ist in Fällen wie folgt aus:

Reader r = null; 
try { 
    r = ...; 
    //do something that could throw an exception 
} finally { 
    if (r != null) { //wouldn't compile without assignment to null 
     r.close(); 
    } 
} 

Da r eine lokale Variable hier ist es Wert muss, bevor es verwendet werden kann, so dass die Zuordnung erforderlich. Wenn die Zuweisung zu NULL im selben Codepfad stattfindet wie die nachfolgende Neuzuweisung und/oder Verwendung, ist dies wahrscheinlich nur eine irreführende Redundanz.

+0

Normalerweise erzeuge ich Code nur mit unveränderlichen Objekten, so dass Memberfelder, die einen Wert im Konstruktor annehmen, normalerweise als * final * in meinem Code markiert sind, was den Punkt irgendwie strittig macht: In diesem Fall kann es einfach nicht zuerst * null * zuweisen und dann im CTOR ändern. – SyntaxT3rr0r

+0

@Webinator: Definitiv. Ein schöner Nebeneffekt der letzten Mitglieder. –

0

JA, dachte viele Male über diese Frage nach.

Für jetzt gebe ich normalerweise einen Anfangswert null für ein Objekt und einen unwichtigen Wert für einfachen Typ. Der Grund, manchmal kann man nicht sicher sein, dass die JRE der Variable einen Anfangswert gibt. Und manchmal müssen Sie beurteilen, ob die Variable null ist, vielleicht vergessen Sie es.Einige Bugs sind leicht zu finden, wenn Variablen einen Anfangswert haben.

Verwandte Themen