2012-11-23 1 views
17

Powiel możliwe:
Why can’t enum’s constructor access static fields?Dlaczego enum Konstruktor nie może uzyskać dostępu polem statycznym

enum Test { 
    e1,e2;  

    int i=0; 
    static int j=5; 

    Test(){ 
    System.out.println(i+" "+j); 
    } 
} 

W powyższym kodzie konstruktor może uzyskać dostęp do zmiennej instancji, ale nie statyczna zmienna J

Przeczytałem odpowiedź odnoszą się do innego autora wszyscy mówią e1 i e2 zainicjowane przed inicjalizacją J (pole statyczne), ale zgodnie ze specyfikacją java, wszystkie statyczne pola zostały zainicjowane, gdy tylko klasa załadowała się do pamięci, czyli przed uruchomieniem konstruktora. Tak więc przed uruchomieniem konstruktora Test() należy zainicjować zmienną statyczną j. Nie jestem w stanie zrozumieć ograniczenia, czy jakiekolwiek ciało mnie zrozumie. Przeczytałem już odpowiedź na pytania: Why can't enum's constructor access static fields? Ale nie jestem zadowolony z odpowiedzi w stylu: -Tworzenie jest wywoływane, zanim wszystkie statyczne pola zostały zainicjalizowane.

Załóżmy, że jeśli wziąć inny przykład z prostym klasy podobnego wyliczenia

class Test{ 
    public static final Test t=new Test(); 
    static int a=5; 

    Test(){ 
    System.out.println(a); 
    } 

    public static void main(String[] args) { 
    } 
} 

Tu według tam argument konstruktora będzie działać przed inicjalizacji pola statycznego i to działa również jak to print 0 (Jak JVM zrobił inicjalizacja). Ale nie ma błędu kompilacji lub nie ma problemu z uruchomieniem. Dlaczego to samo nie dzieje się z enum.

+1

Właściwie to dobre pytanie, nie mogłem zrozumieć, dlaczego tak jest. Może mieć coś z tym, jak kompilator Java kompiluje plik klasy. – Gerbrand

+1

Nie jestem ekspertem od Java, ale czy nie są członkami enum ('e1' i' e2' powyżej) zasadniczo statycznymi członkami 'enum'? I jako takie, gdy * oni * są inicjowane wartościami, konstruktor musi zostać wywołany. Ale 'j' nie został jeszcze zainicjowany? –

+0

Każda enum w Javie to * jak * klasa rozszerzająca 'java.lang.Enum'. Tego 'java.lang.Enum' nie można rozszerzyć o inne inne * normalne * klasy. Twój argument, że "prosta klasa, taka jak enum", daje oczekiwany wynik, jest nieprawidłowy. – Prasanth

Odpowiedz

2

Problem polega na tym, że instancje wyliczenia są tworzone podczas in formalizacji pól statycznych. I stworzyli przed inicjalizacją twoich statycznych pól. Muszą być w statycznych wartościach tablic i statycznie dostępne, więc ma to sens. I jak stwierdzono w anser do "Dlaczego konstruktor enum nie ma dostępu do statycznych pól?", To niefortunne, że dzieje się to przed wszystkimi określonymi przez użytkownika inalizacjami pola statycznego. Ale jeśli został zamieniony, nie można uzyskać dostępu do instancji wyliczeniowych w statycznej inicjalizacji, więc konieczne byłoby umożliwienie statycznego blokowania zarówno przed, jak i po utworzeniu wartości wyliczeniowych.

Nie wiem, czy problem polega na tym, że inicjalizacja wartości wyliczeniowych dotyczy klasy Enum (i obsługiwana jest w szczególności przez JVM (ta logika nie znajduje się w samej klasie Enum) lub ponieważ nie można umieścić pól statycznych przed wartościami wyliczonymi.

dlaczego jest to, że sposób można odpowiedzieć tylko kilka osób (np. Josh Bloch i Neal GPo które są określone jako autorów Enum w javadoc, a może jakieś nieznane innym)

6

Jeśli wyobrazić, w jaki sposób wyliczenia faktycznie wygląda jak klasa, ma sens:

public class Test { 
    // Imagine you cannot move these two statements: 
    public static final Test e1 = new Test(); 
    public static final Test e2 = new Test(); 

    int i=0; 
    static int j=5; 

    private Test(){ 
    System.out.println(i+ " " + j); 
    } 

    static int getJ() { 
    return j; 
    } 


    public static void main(String[] args) { 
    System.out.println(Test.getJ()); 
    } 
} 

Drukuje:

0 0 
0 0 
5 

Jeśli można udostępnić konkretny przykład (zamiast jednego teoretycznego), możemy zasugerować jak przeprojektować kod do osiągnięcia pożądanego rezultatu, pomimo statycznych ograniczeń terenowych.