2010-03-30 14 views

Odpowiedz

4

Jak wspomniano przez innych odpowiedzi, nie, to nie może się zdarzyć. Z przypisanym końcowym statycznym polem może jednak.

class MyClass { 
    private static MyClass myClass = new MyClass(); 
    private static final Object obj = new Object(); 
    public MyClass() { 
    System.out.println(obj); // will print null once 
    } 
} 
+1

Dzięki! A to prowadzi do http://stackoverflow.com/questions/2547713/why-static-fields-are-not-initialized-in-time –

+0

to jest z dawno temu, ale ja po prostu chcę powiedzieć, że choć może to tak się nie dzieje, to mi się przydarza. Jedyne, co mogę myśleć, to to, że to GWT, z którym mam do czynienia, więc to Java jest skompilowana krzyżowo z JScriptem. – Jamie

2

Inicjator Object obj = new Object(); zostanie uruchomiony przed kodem wewnątrz konstruktora, więc obj nie może być null.

Zauważ, że nie będzie to skompilować jeśli nie zainicjować obj wszędzie.

2

roboty dla mnie:

$ cat MyClass.java 
class MyClass { 
    private final Object obj = new Object(); 
    public MyClass() { 
     System.out.println(obj); // may print null? 
    } 
    public static void main(String[] args) { new MyClass(); } 
} 
$javac MyClass.java; java MyClass 
[email protected] 

inicjalizatory Wszystkie pola są kopiowane przez kompilator na początku wszystkich konstruktorów.

Jednak w modelu pamięci Java 5, jeśli pozwolisz this odniesienia „ucieczki” przed końcem konstruktora, inne wątki widać niezainicjowane wartości final pola (tak widział null w tym przypadku).

+0

to nie był mój negatyw, ale o czym ty mówisz? –

+0

Ostatni akapit opisuje jedyną znaną mi sytuację, w której możliwe jest zobaczenie wartości pola końcowego o niezainicjowanej wartości. Zobacz "Jak końcowe pola działają pod nowym JMM?" sekcja http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html –

+0

+1 - patrz również https://www.securecoding.cert.org/confluence/pages/ viewpage.action? pageId = 32833640 –

3

To nie jest możliwe, ponieważ jak wszystkie initializers run before the constructor is invoked.

Variable inicjalizatory jak masz private final Object obj = new Object(); bieg przed konstruktor jest wywoływany. Dotyczy to również bloków inicjalizacyjnych statycznych lub innych.

Jedno zwrócić uwagę podczas korzystania z inicjatorów jest inicjalizatory nie może uczynić naprzód odwołuje Kiedy piszesz inicjatora, nie może odnosić się do wszelkich zmiennych instancji deklarowanych tekstowo po zmienna jest inicjowana.

2

Z prostym przykładem, takim jak twój, nic złego się nie dzieje. Jednakże jest możliwe pole final być widoczne jako zainicjalizowana jeśli używasz wątpliwych praktyk, takich jak wywołanie metody przeciążać w konstruktorze.

Na przykład poniższy program wyświetla "Mój ulubiony kolor ma wartość NULL", mimo że odwołuje się do ostatecznej zmiennej favouriteColour, która jest ustawiona w konstruktorze na "blue".

abstract class SuperClass { 
    final String favouriteColour; 

    SuperClass() { 
     announceFavouriteColour(); 
     favouriteColour = "blue"; 
    } 

    abstract void announceFavouriteColour(); 
} 

public class FinalTest extends SuperClass { 
    void announceFavouriteColour() { 
     System.out.println("My favourite colour is " + favouriteColour); 
    } 

    public static void main(String[] args) { 
     new FinalTest(); 
    } 
} 
Powiązane problemy