2016-05-19 31 views
5

Jestem mylić z wyjściem z poniższego kodu. Wiem, że pierwszy blok statyczny zostanie wykonany po załadowaniu klasy, ale dlaczego moja klasa Test6 nie zostanie załadowana. Czy ktoś może wyjaśnić.Dlaczego moja klasa nie jest ładowana

package com.vikash.General; 

public class Test5 { 

    public static void main(String[] args) { 
     System.out.println(Test6.FOO); 
    } 
    static { 
     System.out.println("Initializing B"); 
    } 
} 
class Test6{ 

    public static final String FOO = "foo"; 
    static { 
     System.out.println("Initializing A"); 
    } 
} 
+0

Otrzymuję o/p Inicjowanie B foo –

Odpowiedz

0

Użyj programu ładującego klasy dostaniesz pożądany wynik

Class.forName("<package>.Test6"); 
+0

Dlaczego nie tylko "Klasa foo = Test6.class"? – Thilo

+1

wszystko by działało. Właśnie dałem, ponieważ OP był zdezorientowany w kwestii ładowania klas. – Helios

+0

Niezupełnie. Wyrażenie takie jak "System.out.println (Test6.FOO)" normalnie również ładuje klasę (ale nie w tym przypadku). – Thilo

2

Wydaje się, ponieważ kompilator jest inline odniesienie do łańcucha dosłownym "foo", więc JRE rzeczywistości nie przeszkadza ładowanie Test6, aby go zdobyć.

Jeśli dokonasz zmian, takich jak:

public static final String FOO = new String("foo"); 

następnie klasa Test6 jest ładowane (i jego static blok zostanie wykonany).

+0

Działa również z literałem, gdy 'FOO' nie jest ostateczny. Ale na wszelki wypadek Twoje rozwiązanie również działa. – Clayn

9

Test6.FOO dotyczy Test6, a pole jest public static final String inicjowane z kompilacji stałej, tak will be inlined by the compiler i Test6 nie musi być umieszczona na wszystkich.

+0

Rzeczywiście. Po usunięciu 'końcowego' inicjalizator statyczny zostanie wywołany – Clayn

+0

@Thilo Czy możesz wyjaśnić" będzie on włączony przez kompilator ". Nie rozumiem. To dla mnie nowość – mubeen

+1

W efekcie kod staje się "System.out.println (" foo ")'. Kompilator zastępuje odniesienie do pola literałem łańcuchowym. W czasie wykonywania 'Test6' nie jest potrzebny dla tego wiersza kodu. – Thilo

-3

Test6 nie został w ogóle zainicjowany.

foo jest statyczne, co oznacza, że ​​można go użyć, zanim klasa zostanie zainicjowana i po załadowaniu klasy.

+3

Nie wiem, czy rozumiem tę odpowiedź całkowicie, ale jestem prawie pewien, że to jest złe i nie odpowiada na pytanie. – SomeJavaGuy

+0

Jeśli nie rozumiesz, dlaczego jesteś taki pewien, że to źle? – sotondolphin

+0

ponieważ nie wyjaśnia, dlaczego 'Test6' nie jest załadowany. Po prostu następuje mylące wyjaśnienie "foo is static", które w tym momencie nie ma nic wspólnego z zachowaniem. Właściwie to jest pytanie, pomimo '' '' '' '' static'', dlaczego nie ładuje 'Test6' i stąd nazywa' statyczny blok inicjalizatora' – SomeJavaGuy