2013-05-07 3 views
6

Ich habe etwas in statischen Initialisierern bemerkt, was ein Fehler im Javac sein könnte. Ich habe ein Szenario konstruiert, in dem ich einer Variablen einen Wert zuweisen, diesen Wert aber nicht zurücklesen kann.Statischer Initialisiererfehler, wenn er vor der Deklaration platziert wurde

Die beiden Beispiele sind unten, die erste kompiliert gut, die zweite erhält einen Fehler beim Versuch, einen Wert von tmp zu lesen, aber aus irgendeinem Grund ist die Zuweisung eines Wertes zu tmp erlaubt. Ich könnte verstehen, wenn es die Variable weder lesen noch schreiben könnte, da tmp nach dem statischen Initialisierer deklariert wird, aber ein Fehler auf nur einem davon macht für mich keinen Sinn.

//Compiles Successfully: 
public class Script 
{ 
    public static Object tmp; 
    static 
    { 
     tmp = new Object(); 
     System.out.println(tmp); 
    } 

} 

//error only on the read but not the assignment 
public class Script 
{ 

    static 
    { 
     tmp = new Object(); 
     System.out.println(tmp); 
    } 
    public static Object tmp; 
} 

um den Punkt weiter zu betonen, kompiliert dies erfolgreich.

public class Script 
{ 

    static 
    { 
     tmp = new Object(); 
    } 
    public static Object tmp; 
} 
+0

Ich glaube [eine Antwort auf eine ähnliche Frage] [1] beantwortet diese Frage besser als ich kann. Es ist ein seltsames Verhalten, aber kein Fehler. Es macht, was es tun soll. [1]: http://stackoverflow.com/a/10035928/348975 – emory

+0

Ich bin mir nicht sicher, dass es, statische Initialisierer gibt es, um die Variablen von ihrem Standardwert zu initialisieren. das heißt statisch int v = 1; entspricht statisch int v; static {v = 1;} –

+0

@Dukeling Ich schrieb meinen Kommentar als Antwort und StackOverflow stellte fest, dass meine Antwort trivial war (ich denke, das bedeutet zu kurz) und automatisch zu einem Kommentar konvertiert wurde, aber offensichtlich die Links durcheinander brachte. – emory

Antwort

3

Es scheint dies in der Spezifikation definiert ist (siehe JLS 8.3.2.3):

Die Erklärung eines Mitglieds textlich erscheinen muss, bevor es nur eine Instanz (jeweils statisch, wenn das Mitglied verwendet wird, ist) Feld eine Klasse oder Schnittstelle C und alle folgenden Bedingungen halten:

  • Die Verwendung erfolgt in einer Instanz (jeweils statisch) vari fähiger Initialisierer von C oder in einer Instanz (bzw. statischer) Initialisierer
    von

  • Die Verwendung ist nicht auf der linken Seite einer Aufgabe.

  • Die Verwendung erfolgt über einen einfachen Namen.

  • C ist die innerste Klasse oder Schnittstelle, die die Verwendung einschließt.

Wenn also die Nutzung auf der linken Seite einer Zuweisung ist, dann ist es legal, da die zweite nicht mehr hält.

+0

Ok, ich kaufe, dass es Teil der Spezifikation ist, immer noch scheint das eine sehr seltsame Sache zu spezifizieren –

+0

Manchmal denke ich, Java braucht mehr als nur eine Spezifikation, sondern auch ein anderes Buch, das die Entscheidungen erklärt. Ich hoffe, dass jemand mehr Licht in diese Sache bringen kann, aber die Spezifikation ist die beste, die ich herausfinden kann. –

Verwandte Themen