2014-12-16 17 views
20

Zum Beispiel Code betrachten Snap unten:Warum nicht setzen wir den Wert der statischen endgültigen Variablen in statischen Block durch Klassennamen

public static final int a; 
public static final int b; 

static { 
    a = 8;  // it's working 
    Test.b = 10; // compilation error Test.b cannot be assigned. 
} 

Warum können wir Test.b = 10; in einem statischen Block des Test nicht verwenden Klasse selbst? Ohne den Klassennamen funktioniert es gut.

Gibt es einen Grund dafür?

+3

Weil Ihre Klasse noch nicht initialisiert ist, wenn Sie sich in einem statischen Initialisierer befinden? Auch wahrscheinlich, weil die JLS es verbietet ... – fge

+2

Interessieren Sie sich für "welches Bit der JLS verbietet das" oder "Warum wurde die Sprache so entworfen?"? –

+0

Könnte hier falsch sein, aber vielleicht ist es, weil Sie 'Test.b' als' final' deklariert haben –

Antwort

7

Eine statische Endvariable muss vor der Verwendung initialisiert werden. Es kann entweder direkt zur Deklarationszeit oder in einem statischen Block initialisiert werden.

Aber wenn Sie class.var = x verwenden, wird es nicht als eine Initialisierung, sondern als eine Zuweisung gesehen.

Bei einem JDK 7 kann der Fehler der endgültigen Variablen keinen Wert zuweisen.

Das erklärt, warum es funktioniert, wenn Sie das final

Stichwort entfernen
class Test { 

    static final int a = 2; // initialization at declaration time 
    static final int b; 
    static final int c; 

    static { 
     b = 4; // initialization in static block 
     Test.c = 6; // error : cannot assign a value to final variable c 
    } 
    ... 

} 

EDIT

Im JLS das richtige Wort für die Initialisierung ist definitiven assignement

Auszug aus dem JLS:

Für jeden Zugriff eines lokalen v Das letzte Feld x, x muss definitiv vor dem Zugriff zugewiesen sein, oder es tritt ein Fehler bei der Kompilierung auf.

Ebenso muss jede leere letzte Variable höchstens einmal zugewiesen werden; es muss definitiv nicht zugewiesen sein, wenn eine Zuweisung zu ihm auftritt.

Eine solche Zuweisung definiert ist, wenn das Auftreten und nur dann, wenn entweder die einfache Name der Variable (oder, für ein Feld, ihren einfachen Namen dadurch qualifiziert) auf der linken Seite eines auftritt Aufgabenverwalter.

Für jede Zuordnung zu einer leeren letzten Variable, muss die Variable vor der Zuweisung definitiv nicht zugeordnet sein, oder ein Fehler bei der Kompilierung auftritt.

betonen meine, aber ich denke, das ist der wahre Grund für den Fehler.

+1

Ich denke nicht, dass das recht ist, obwohl es in der richtigen Richtung sein muss. Dies besagt, dass Sie keine leere letzte Variable zuweisen können, es sei denn, es ist definitiv nicht zugewiesen zu diesem Zeitpunkt, aber es ist definitiv nicht zugewiesen. Es scheint mir nicht, das Bit, das du zitierst, zu verletzen. –

+0

@ chiastic-security: Ich bin nicht wirklich ein Anwalt, und Englisch ist nicht meine erste Sprache, indem ich denke, dass das wichtige Wort hier ist * einfacher Name * weil 'Test.b' ist kein einfacher Name. –

+0

Ja, dieser Satz ist wichtig, aber alles, was er sagt, ist, dass "Test.b = 10" nicht "eine solche Zuweisung" ist, d. H. Dieser Code ist für dieses Bit der JLS nicht sichtbar. –