2014-05-22 9 views
5

Jestem zmieszany z procesem ładowania klasy. Jaka jest kolejność wykonywania elementów klasy?Co tak naprawdę dzieje się podczas ładowania klasy w języku Java?

zobacz:

class L { 

    static void fr(){ 
     a=1; 
     b=3; 
     a=b; 
    } 

    static{ 
     a=3; 
     b=1; 
     a=b;// here the problem:cannot reference a field before it is defined 
    } 

    static int a; 
    static int b; 

    public static void main(String args[]) { 

    } 
} 

Ilekroć przenieść oświadczeń a i b do góry przed statycznego bloku, kompilacja działa dobrze. Muszę więc zrozumieć, jak działają te rzeczy, aby rozwiązać powyższy problem.

Odpowiedz

4

W języku Java niedozwolone jest odwoływanie się do zmiennej klasy przed jej zadeklarowaniem, o ile nie jest to jej inicjowanie. Java uruchomi inicjalizatory w klasie w kolejności tekstowej.

Section 12.4.2 of the JLS stany:

Następnie wykonać zarówno klasy zmiennej inicjatorów i statycznych inicjatorów klasy lub inicjatorów dziedzinie interfejsu w celu tekstowej, tak jakby były one pojedynczym bloku.

Section 8.3.3 of the JLS stany:

Zastosowanie zmiennych klasowych, których deklaracje pojawiają tekstowo po stosowanie jest ograniczone czasem, choć te są zmienne w zakresie klasy (§6.3). W szczególności, jest to błąd kompilacji, jeśli wszystkie następujące warunki są prawdziwe:

  • Deklaracja zmiennej klasy w klasy lub interfejsu C wydaje tekstowo po wykorzystaniu zmiennej klasy;

  • Użycie jest prostą nazwą w inicjalizatorze zmiennych klasy C lub statycznym inicjalizatorze C;

  • Użycie nie znajduje się po lewej stronie zadania;

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

Wszystkie one są prawdziwe. Deklaracja pojawia się po użyciu w a=b;. Jest w statycznym inicjalizatorze. Nie jest po lewej stronie zadania i jest najgłębszą (jedyną) klasą.

Najprostszym sposobem skompilowania jest przeniesienie deklaracji nad statycznym inicjatorem w kodzie źródłowym.

Co ciekawe, zastąpienie a=b; przez a=L.b; również doprowadzi do kompilacji, ponieważ odniesienie do b nie jest już "proste".

0

Najpierw zostanie załadowana klasa i zweryfikowana ogólna struktura. Następnie sprawdzane są metody i sprawdzane są powiązania zewnętrzne. Następnie wykonywany jest statyczny init. Jest to wykonywane po wykonaniu bloku statycznego.

Ale twój problem jest najwyraźniej z kompilatorem, a nie ładowaniem klasy. Musisz przenieść swoje deklaracje zmiennych statycznych powyżej bloku statycznego. Nie ma nic wspólnego z ładowaniem klas.

Podpowiedź: poznaj różnicę między błędem podczas kompilacji a wyjątkiem wykonawczym. To, co widzisz, było komunikatem o błędzie z kompilatora. (I masz szczęście, że nie złapałeś cholernego piekła i nie oddałeś głosów za nieuwzględnienie komunikatu błędu EXACT w swoim pytaniu.)

Powiązane problemy