2010-03-30 6 views

Respuesta

4

Como se discutió en otras respuestas, no, eso no puede suceder. Sin embargo, con un campo estático final asignado, puede hacerlo.

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

Gracias! Y esto lleva a http://stackoverflow.com/questions/2547713/why-static-fields-are-not-initialized-in-time –

+0

Esto es de hace mucho tiempo, pero solo quiero decir que aunque esto puede Sucede, me sucede a mí. Lo único que se me ocurre es que es porque es GWT con lo que estoy tratando, por lo que es Java el que se compila en forma cruzada con JScript. – Jamie

2

El inicializador Object obj = new Object(); se ejecutará antes del código dentro del constructor, por lo que obj no puede ser null.

Tenga en cuenta que esto no se compilaría si no inicializara obj en cualquier lugar.

2

funciona para mí:

$ 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] 

Todos los inicializadores de campo son copiados por el compilador en el comienzo de todos los constructores.

Sin embargo, bajo el modelo de memoria de Java 5, si se deja que el this referencia 'escapar' antes de que finalice el constructor, otros hilos pueden ver los valores sin inicializar de final campos (por lo que podía ver null en este caso).

+0

no era mi negativa, pero ¿de qué estás hablando? –

+0

El último párrafo describe la única situación que conozco en la que es posible ver el valor de un campo final que tiene su valor no inicializado. Consulte "¿Cómo funcionan los campos finales en el nuevo JMM?" sección de http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html –

+0

+1 - ver también https://www.securecoding.cert.org/confluence/pages/ viewpage.action? pageId = 32833640 –

3

Esto no es posible como todos initializers run before the constructor is invoked.

Inicializadores de variables como los que tiene private final Object obj = new Object(); ejecutar antes de invocar el constructor. Esto también es cierto para bloques de inicialización estáticos o de otro tipo.

Una cosa a tener en cuenta al utilizar inicializadores es que inicializadores no pueden hacer hacia adelante hace referencia a Cuando se escribe un inicializador, no se puede hacer referencia a las variables de instancia declaradas textualmente después de la variable que se está inicializado.

2

Con un ejemplo simple como el suyo, no puede pasar nada malo. Sin embargo, es posible para que un campo final sea visible como no inicializado si utiliza prácticas cuestionables, como llamar a un método sobrescribible en su constructor. Por ejemplo, el siguiente programa imprime "Mi color favorito es nulo", aunque hace referencia a la variable final favouriteColour, que se establece en "blue" en el constructor.

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(); 
    } 
} 
Cuestiones relacionadas