Orden de carga en variables yu bloques de codigo java

Hola a todos, tengo una enorme duda que el libro de certificacion no me ha aclarado y con el cual estoy enredado, espero pueda alguien aqui explicarmelo, primero, agregare el codigo de dos clases que tengo(clase A y B) y los resultados de las ejecuciones de los mismos programas:

Ejecutando el siguiente codigo

public class B {
        public static void main(String[] args) {
                System.out.println("****inicializando a new****");
                A b = new A();
                System.out.println("****valores despues del contructor****");
                System.out.println(A.x + " , "  + b.y);
        }
}

Para el Caso 1)

public class A {
        //inicializando variables
        public static int x = 0;
        public int y = 0;
        //iniciando bloques
        static {        System.out.println("bloque estatico 1");x = 1;}
        static {        System.out.println("bloque estatico 2");x = 2;}
        //bloques de codigo
        {
                System.out.println("bloque 1");
                y = 1;
        }
        {
                System.out.println("bloque 2");
                y = 2;
        }
        //constructor
        public A() {
                System.out.println("entrando al constructor");
        }
}

Obtengo

****inicializando a new****
bloque estatico 1
bloque estatico 2
bloque 1
bloque 2
entrando al constructor
****valores despues del contructor****
2 , 2

Para el Caso 2)

public class A {
        //iniciando bloques
        static {        System.out.println("bloque estatico 1");x = 1;}
        static {        System.out.println("bloque estatico 2");x = 2;}
        //bloques de codigo
        {
                System.out.println("bloque 1");
                y = 1;
        }
        {
                System.out.println("bloque 2");
                y = 2;
        }
        //inicializando variables
        public static int x = 0;
        public int y = 0;
        //constructor
        public A() {
                System.out.println("entrando al constructor");
        }
}

Obtengo

****inicializando a new****
bloque estatico 1
bloque estatico 2
bloque 1
bloque 2
entrando al constructor
****valores despues del contructor****
0 , 0

Para el Caso 3)

public class A {
        //inicializando variables
        public static int x = 0;
        public int y = 0;
        //iniciando bloques
        static {        System.out.println("bloque estatico 2");x = 2;}
        static {        System.out.println("bloque estatico 1");x = 1;}
        //bloques de codigo
        {
                System.out.println("bloque 2");
                y = 2;
        }
        {
                System.out.println("bloque 1");
                y = 1;
        }
        //constructor
        public A() {
                System.out.println("entrando al constructor");
        }
}

Obtengo

****inicializando a new****
bloque estatico 2
bloque estatico 1
bloque 2
bloque 1
entrando al constructor
****valores despues del contructor****
1 , 1

La duda es, que se ejecuta primero?
Como pudieron ver, segun el orden en que ponga las cosas parace que se hace una u otra cosa primero

Pero por ejemplo, si pongo algo como:

public class A {
       //bloque
       {
                System.out.println("bloque 1");
                y++;
        }
        //inicializando variables
        public static int x = 0;
        public int y = 0;
        //iniciando bloques

No compila, pueden creerlo? me dice que la variable debeinicializarse antes de ser utilizada.

De verdad que estoy hecho un lio, todo cambia segun el orden al parecer, o quizas yo este equivocado, el caso es que no veo el orden y los porques de como se realiza todo esto, obvio la parte de "primero se hace la super clase Object y su contructor y bla bla bla", eso ya lo se, este es el caso que os presento y que no me deja dormir.

EN QUE ORDEN SE REALIZAN LAS COSAS Y PORQUE? porque con el ultimo codigo mencionado no compila?

Favor de abstenerse quien solo suponga, necesito la regla tal y como es y no suposiciones(eso lo puedo hacer tambien yo).

De antemano mil gracias compañeros...

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Interesante.Simplificando el

Interesante.

Simplificando el ejemplo:

//Compila
class A {
    {
        y = 1;
    }
    int y;
}
// No compila
class A {
    {
        y++;
    }
    int y;
}

Y mas sorprendente aun, esto si compila

// Sorprendente, si compila
class A {
    {
        this.y++;
    }
    int y;
}

Es una regla que tiene el compilador.

Voy a inventar una razón ( porque no necesariamente es esa ) pero al compilar, se debe de determinar a quien le pertenecen las variables, si son locales, de clase, de instancia.

- Si ya esta definida y entonces se sabe que 'y' es una variable de instancia ( o local o de clase, pero ya se sabe).
- Si no esta definida y se usa su nombre "complejo" ( en el tercer caso this.y) igual ya se sabe que es de instancia ( o de clase si se usa por ejemplo A.y )
- Pero si no esta definida, se usa su nombre simple y ademas se usa del lado derecho de la expresión ( o sea que es la que va a dar el valor ) el compilador no sabe donde ponerla y se niega a continuar. En mi primer ejemplo: class A { { y = 1; } int y;} y esta del lado izq. de la expresión por eso si compila.

Y ya. Lo del valor final es correcto, se ejecuta de arriba hacia abajo y el valor final es el ultimo que ocurrió.

Espero que esto aclare tu duda.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3 ( La ultima palabra en cuanto a Java )
http://www.xyzws.com/Javafaq/what-are-the-forward-reference-rules/9 ( El blog donde encontre la ayuda )
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6425594 ( un bug relacionado)

Y ya. Tan tan.

P.D. Aprovechando: las variables con el modificador static se llaman de clase no estáticas, como muchos las llaman. No hace gran diferencia en realidad y quizá hasta raya en la pedantería, pero en la especificación se describen las variables de clase, dice que son y como se comportan, pero no habla de variables estáticas.

Imagen de arcioneo

Muchas gracias

Mi estimabilísimo, parece ser que tienes la boca llena de rozan.

Aunque es algo extraño que el compilador no sepa si es una variable de clase o instancia, pero si reconozca su existencia cuando esta del lado izquierdo.

Es extraño que el libro de certificación(consulte 3) no mencione un detalle así.

Por ultimo solo falto observar que se ejecuta efectivamente el de arriba a abajo en orden de aparición, pero siempre se ejecuta en el siguiente orden:

1) Miembros de clase(da igual si son bloques o variables)
2) Miembros de instancia(da igual si son bloques o variables)
3) Finalmente el constructor

Muchas gracias....

Viste que esta es mi

Viste que esta es mi interpretación de la regla? La especificación del lenguaje no explica porque es ilegal solo dice que lo es. El libro donde sacaste el ejemplo debería de explicar porque.

No seria raro que al compilador no le importara mucho por un momento que hacer con una var del lado izq.. Finalmente es el lado derecho el que le va a dar el tipo

Por ejemplo

....
y = 1;
z = System.out;

A 'y' le van a asignar un entero y a 'z' lo que sea 'System.out', puede ser que de momento esa información sea suficiente, aun asi si no se definen esas variables después el compilador mandara un error.