Se puede encontrar una sección en JLS: §12.4.2 .
Procedimiento de inicialización detallado:
9.A continuación, ejecute los inicializadores de variables 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 se compilan -Las constantes de tiempo se inicializan primero
Entonces, las tres variables estáticas se inicializarán una por una en orden textual.
Entonces
static A obj = new A();
//num1 = 1, num2 = 1;
static int num1;
//this is initilized first, see below.
static int num2=0;
//num1 = 1, num2 = 0;
Si cambio el orden a:
static int num1;
static int num2=0;
static A obj = new A();
El resultado será 1,1
.
Tenga en cuenta que static int num1;
no es un inicializador de variable porque ( §8.3.2 ):
Si un declarador de campo contiene un inicializador de variable, entonces tiene la semántica de una asignación (§15.26) a la variable declarada y: Si el declarador es para una variable de clase (es decir, un campo estático), entonces el inicializador de variable es evaluado y la asignación realizada exactamente una vez, cuando se inicializa la clase
Y esta variable de clase se inicializa cuando se crea la clase. Esto sucede primero ( §4.12.5 ).
Cada variable en un programa debe tener un valor antes de que se use su valor: Cada variable de clase, variable de instancia o componente de matriz se inicializa con un valor predeterminado cuando se crea (§15.9, §15.10): Para el tipo byte, el valor predeterminado es cero, es decir, el valor de (byte) 0. Para el tipo corto, el valor predeterminado es cero, es decir, el valor de (corto) 0. Para el tipo int, el valor predeterminado es cero, es decir, 0. Para el tipo long, el valor predeterminado es cero, es decir, 0L. Para el tipo flotante, el valor predeterminado es cero positivo, es decir, 0.0f. Para el tipo double, el valor predeterminado es cero positivo, es decir, 0.0d. Para el tipo char, el valor predeterminado es el carácter nulo, es decir, '\ u0000'. Para el tipo booleano, el valor predeterminado es falso. Para todos los tipos de referencia (§4.3), el valor predeterminado es nulo.