explicar ordem de compilação java

v2 é nulo quando entra no c'tor de A na primeira vez, mas se eu colocarv2declaração e inicialização antes deinstance terá um valor; por que é isso?

public class A {

    private static final String v1 = new String(new byte[]{'a', 'b'});

    private static A instance = new A();

    private static final String v2 = new String(new byte[]{'b', 'c'});

    private A() {
        System.out.printf("A c'tor\tv1 [%s]\tv2 [%s]\n", v1, v2);
    }

    public static void main(String[] args) {
        System.out.println("start main");
        new A();
        System.out.println("end main");
    }
}

resultado:

    A c'tor v1 [ab] v2 [null]
    start main
    A c'tor v1 [ab] v2 [bc]
    end main

Além disso, se eu mudarv2a inicialização de ser:

private static final String v2 = "ab";

inicializav2e a saída é:

A c'tor v1 [ab] v2 [ab]
start main
A c'tor v1 [ab] v2 [ab]
end main

Editar

outro teste para a segunda parte:

public class A {

    private static final String v1 = new String(new byte[]{'a', 'b'});

    private static transient A instance = new A();

    private static final String v2 = new String(new byte[]{'b', 'c'});
    private static final String v3 = new String("ab");
    private static final String v4 = "ab";

    private A() {
        System.out.printf("A c'tor\tv1 [%s] v2 [%s] v3 [%s] v4 [%s]\n", v1, v2, v3, v4);
    }

    public static void main(String[] args) {
        System.out.println("start main");
        new A();
        System.out.println("end main");
    }
}

resultado:

A c'tor v1 [ab] v2 [null] v3 [null] v4 [ab]
start main
A c'tor v1 [ab] v2 [bc] v3 [ab] v4 [ab]
end main

questionAnswers(1)

yourAnswerToTheQuestion