2009-10-13 5 views

Antwort

54

Es gab eine question about this very recently for C# ... - lesen Sie die Antworten auch dort, da es im Grunde die gleiche Sache ist. Vielleicht finden Sie auch Eric Lippert's recent blog post interessant; es ist zumindest in der gleichen Gegend, obwohl es einen etwas anderen Schub hat.

Grundsätzlich ist es eine gute Sache, eine Variable mit einem Wert zu versehen, bevor Sie sie lesen. Es bedeutet, dass Sie nicht versehentlich etwas lesen, was Sie nicht vorhatten. Ja, Variablen könnten Standardwerte haben - aber ist es nicht besser, wenn der Compiler den Bug abfangen kann, wenn er beweisen kann, dass Sie versuchen, etwas zu lesen, das noch nicht zugewiesen wurde? Wenn Sie einer lokalen Variablen einen Standardwert zuweisen möchten, können Sie dies immer explizit zuweisen.

Jetzt ist das für lokale Variablen in Ordnung - aber zum Beispiel und statische Variablen, der Compiler hat keine Möglichkeit zu wissen, in welcher Reihenfolge Methoden aufgerufen werden. Wird ein Property "Setter" vor dem "Getter" aufgerufen? Es hat keine Möglichkeit zu wissen, also kann es dich nicht vor der Gefahr warnen. Deshalb werden die Standardwerte für zB/statische Variablen verwendet - zumindest dann erhalten Sie einen bekannten Wert (0, false, null usw.) statt nur "was immer gerade im Speicher war." (Es beseitigt auch das potenzielle Sicherheitsproblem beim Lesen sensibler Daten, die nicht explizit gelöscht wurden.)

+0

Was ich nicht verstehe ist, wenn ein Objekt standardmäßig Null ist, warum müssen Sie es null zuweisen? Ich denke, dass die Java-Leute entschieden haben, dass es besser ist, in diesem Fall explizit zu sein, aber ich bin mir nicht sicher, ob ich dem zustimme. –

+5

Ein Objekt ist nicht null. Eine * Variable * kann null sein, aber kein Objekt. Und eine lokale Variable * hat keinen Standardwert ... genau deshalb, weil Sie keine haben, müssen Sie ihr einen nützlichen Wert geben, bevor sie gelesen wird. Wenn du diesen Wert auf Null setzen willst, ist das in Ordnung ... aber ich mag es eher, wenn der Compiler mir sagt, wenn ich etwas lese, das vielleicht nicht initialisiert wurde ... –

+0

@Jon Was meinst du mit "Es auch beseitigt das potenzielle Sicherheitsproblem beim Lesen sensibler Daten, die nicht explizit gelöscht wurden. " ? Kannst du das bitte etwas erklären? – Geek

1

Lokale Variablen und Primitive sollten vor der Verwendung initialisiert werden, da Sie wissen, was Sie von den Werten erwarten können. Historisch gesehen, wenn eine neue Variable erstellt wurde, würde sie zufällige Werte aus dem Speicher enthalten [und man könnte den Wert nicht vorhersagen]. Java erfordert dies auch, weil es das Vorhandensein von verwaisten Variablen verhindert.

0

In der Praxis müssen alle Variablen vor der Verwendung initialisiert werden.

Ich kann mir nicht vorstellen, wann Sie eine Variable verwenden möchten, bevor Sie ihren Wert festlegen (es sei denn, Sie vergleichen ihn mit null).

7

Nun, im Fall der lokalen Variablen ist klar, was es bedeutet "vor", da der Programmablauf zwischen Deklaration (in Methode) und Referenz sequenziell ist. Im Falle von Feldern, die außerhalb der Methode deklariert sind, weiß der Compiler niemals, welcher Code verwendet wird, und kann daher keinen Fehler erzeugen, da möglicherweise eine andere Methode das Feld vor der Verwendung initialisiert.

+0

+1 für "der Programmablauf zwischen Deklaration (in Methode) und Referenz ist sequentiell." – luigi7up

3

Nicht ganz richtig. Lokale Variablen müssen nur initialisiert werden, wenn sie Referenz sind. Eine lokale Variable kann nicht initialisiert werden, wenn sie nie referenziert wird. Zum Beispiel:

int x; // Valid 
int y; 
println("y=" + y); // Not valid since y's value has never been assigned 
6

In Java, Klassen- und Instanzvariablen annehmen einen Standardwert (null, 0, false), wenn sie nicht manuell initialisiert werden. Lokale Variablen haben jedoch keinen Standardwert. Wenn einer lokalen Variablen kein Wert zugewiesen wurde, verweigert der Compiler die Kompilierung des Codes, der ihn liest. IMHO, dies führt zu der Schlussfolgerung, dass das Initialisieren einer lokalen Variable mit einem Standardwert (wie null, was später zu einer NullPointerException führen kann), wenn es deklariert wird, tatsächlich eine schlechte Sache ist. Betrachten Sie das folgende Beispiel:

Object o; 
if (<some boolean condition>) 
    o = <some value>; 
else 
    o = <some other value>; 
System.out.println(o); 

Eine Initialisierung von o mit null ist völlig unnötig, da die Java-Compiler prüft bei der Kompilierung, dass jeder Code-Pfad o initialisiert (mit entweder null oder einem Nicht-Null-Wert) vor Die Variable wird gelesen.Das bedeutet, dass der Compiler es ablehnt, die Zeile System.out.println(o); zu kompilieren, wenn Sie eine der beiden Initialisierungen der Variablen o im obigen Code-Snippet auskommentieren.

Dies gilt für Java und vielleicht nur für Java. Ich kenne keine Sprache wie C#. In guten alten C (und vielleicht C++) ist es jedoch immer noch empfehlenswert Variablen immer zu initialisieren wenn AFAIK deklariert wird. Solche "Oldschool" Programmiersprachen könnten der Grund dafür sein, dass die Empfehlung, Variablen immer zu initialisieren, in Büchern und Diskussionen über moderne Sprachen wie Java auftaucht, wo die Kompilierung verfolgt, ob eine Variable initialisiert wurde oder nicht.

+0

Die "old-school" Sprachen empfehlen, eine Variable erst dann zu deklarieren, wenn Sie einen Wert eingeben müssen. :-) –

+0

Betrachten Sie das obige Beispiel. Wie kann ein Wert in eine Variable eingegeben werden, wenn der Wert vom Ergebnis einer komplexen if-Anweisung abhängt? IMHO, die Regel, die Sie vorschlagen, hat ein großes Problem. – Sven

+0

Wenn der Wert einige komplexe Berechnungen benötigt, können Sie diese in eine separate Funktion einfügen und den Funktionsaufruf als Initialisierer verwenden. –

Verwandte Themen