2013-05-07 8 views
6

Zauważyłem coś w statycznych inicjalizatorach, co może być błędem w javacu. Skonstruowałem scenariusz, w którym mogę przypisać zmiennej wartość, ale nie odczytałem tej wartości z powrotem.Statyczny błąd inicjatora, jeśli został umieszczony przed deklaracją

Dwa przykłady znajdują się poniżej, pierwszy kompiluje dobrze, drugi dostaje błąd, gdy próbuje odczytać wartość z tmp, ale z jakiegoś powodu przypisanie wartości do tmp jest dozwolone. Mogłem zrozumieć, czy nie można odczytać ani zapisać do zmiennej, ponieważ tmp jest zadeklarowany po statycznym inicjatorze, ale błąd w jednym z nich nie ma dla mnie sensu.

//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; 
} 

dla dodatkowego podkreślenia, to kompiluje się pomyślnie.

public class Script 
{ 

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

Wierzę, że [odpowiedź na podobne pytanie] [1] odpowiada na to pytanie lepiej niż ja. To dziwne zachowanie, ale nie błąd. Robi to, co ma robić. [1]: http://stackoverflow.com/a/10035928/348975 – emory

+0

Nie jestem pewien, czy tak jest, inicjatory statyczne są tam, aby zainicjować zmienne od ich wartości domyślnej. co oznacza, że ​​static int v = 1; jest równoważne statycznej int v; static {v = 1;} –

+0

@Dukeling Napisałem swój komentarz jako odpowiedź, a StackOverflow stwierdził, że moja odpowiedź była banalna (myślę, że to za krótko) i automagicznie przekonwertowałem ją do komentarza, ale ewidentnie sflaczałam linki. – emory

Odpowiedz

3

Wydaje się to jest zdefiniowane w specyfikacji (Patrz JLS 8.3.2.3):

Oświadczenie członka musi pojawić tekstowo zanim będzie stosowane tylko wtedy, gdy członek jest instancją (odpowiednio statyczna) Dziedzina klasy lub interfejs C, a wszystkie z następujących warunków przytrzymanie:

  • Stosowanie następuje w przypadku, odpowiednio, (statyczne) o zmiennym w stanie inicjalizator C lub instancji (odpowiednio statyczny) inicjatora
    z C.

  • Użycie nie znajduje się po lewej stronie zlecenia.

  • Użycie odbywa się za pomocą prostej nazwy.

  • C jest najgłębszą klasą lub interfejsem zamykającym użycie.

Więc jeśli użycie jest na lewej stronie przypisania, to jest legalne, ponieważ druga nie posiada już.

+0

OK, kupuję, że jest to część specyfikacji, nadal wydaje się bardzo dziwną rzeczą, aby określić –

+0

Czasami myślę, że Java potrzebuje czegoś więcej niż tylko specyfikację, ale także inną książkę, która wyjaśnia podejmowane przez nią decyzje. Mam nadzieję, że ktoś może rzucić więcej światła na ten temat, ale specyfikacja jest najlepsza, jaką mogę znaleźć. –

Powiązane problemy