java - poner - ¿Por qué los campos parecen estar inicializados antes que el constructor?
setbounds java (5)
Que esta pasando..
La primera línea que se ejecuta es este public static Dog dog = new Dog();
. Ahora, hay 2 cosas que deben tenerse en cuenta.
final int
hace que sea una constante de tiempo de compilación . Entonces,-5
ya está codificado en su código.La llamada a nuevo
Dog()
se realiza y se llama al constructor, que establece el valor en0
+-5
=-5
.
cambia val2
a final
luego verás la diferencia (obtendrás -2
como respuesta).
Nota: los campos estáticos se inicializan como y cómo se encuentran.
public class Dog {
public static Dog dog = new Dog();
static final int val1 = -5;
static int val2 = 3;
public int val3;
public Dog() {
val3 = val1 + val2;
}
public static void main(String[] args) {
System.out.println(Dog.dog.val3);
}
}
La salida es -5
A partir de este resultado, parece que la inicialización de val2
es antes de la finalización del miembro de dog
y su creación de instancias.
¿Por qué este orden es así?
Secuencia de declaración variable. La static final int val1
se inicializa primero porque es una constante. Sin embargo, static int val2
sigue siendo 0
en el momento public static Dog dog = new Dog();
se crea una instancia.
Secuencia de inicialización en tu prueba;
-
static final int val1 = -5;
// constante como final estático -
public static Dog dog = new Dog();
// luego ''dog'' se inicializa pero su miembro val2 no se ha inicializado -
static int val2 = 3;
// en el último ''val2'' se inicializa
Este cambio de código dará como resultado -2
;
public class Dog {
//public static Dog dog = new Dog();
static final int val1 = -5;
static int val2 = 3;
public int val3;
public static Dog dog = new Dog(); //moved here
public Dog() {
val3 = val1 + val2;
}
public static void main(String[] args) {
System.out.println(Dog.dog.val3);
}
}
Si mueve su instancia de perro al final, puede encontrar que la salida se convierte en -2
public class Dog {
static final int val1 = -5;// This is final, so will be initialized at compile time
static int val2 = 3;
public int val3;
public static Dog dog = new Dog();//move to here
public Dog() {
val3 = val1 + val2;
}
public static void main(String[] args) {
System.out.println(Dog.dog.val3);//output will be -2
}
}
Los campos finales (cuyos valores son expresiones constantes en tiempo de compilación) se inicializarán primero , y luego el resto se ejecutará en orden textual.
Por lo tanto, en su caso, cuando se inicializa la instancia de perro, static int val2
(0) aún no está inicializada, mientras que static final int val1
(-5) sí, ya que es definitiva.
http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#12.4.2 declara que:
ejecute los inicializadores de variable de clase y los inicializadores estáticos de la clase, o los inicializadores de campo de la interfaz, en orden textual , como si fueran un solo bloque, excepto que las variables de clase final y los campos de interfaces cuyos valores son constantes de tiempo de compilación son inicializado primero
Actualizado un nuevo documento
Aquí está la versión jdk7 de http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2
campo final está en el paso 6:
Luego, inicialice las variables de la clase final y los campos de las interfaces cuyos valores son expresiones constantes en tiempo de compilación
Mientras el campo estático está en el paso 9:
A continuación, ejecute los inicializadores de variable de clase y los inicializadores estáticos de la clase, o los inicializadores de campo de la interfaz, en orden textual, como si fueran un solo bloque.
Todas las variables estáticas se inicializan en un constructor estático separado, que se ejecuta en la carga de clases. En el mismo orden en que aparecen en el código. Su ejemplo se compila en algo como esto:
public class Dog {
public static Dog dog;
static final int val1 = -5;
static int val2;
public int val3;
static {
dog = new Dog();
val2 = 3;
}
public Dog() {
val3 = val1 + val2;
}
public static void main(String[] args) {
System.out.println(Dog.dog.val3);
}
}
Por eso es importante el orden de las variables de clase / instancia. La ejecución del constructor de clases ocurre al final de la inicialización. Las constantes se resuelven antes. Para obtener más información, consulte Creación de nuevas instancias de clase .