关于java的初始化顺序

最近在研究java基础,对于java初始化的顺序一直没有搞清楚,找了很多资料和文章也还是依然费解。于是决定,自己研究,终于在一个小风嗖嗖的晚上搞清楚了order of initialization,现在分享给大家!
第一步:find class:这个时候jvm会找寻.class文件,.class像个产品的磨具一样,是用来产生object产品的而不是.class本身。
第二步:create object class:往往很少有人注意到这点,这也是一个oject也同样占用内存资源可是和传统意义上的object不一样,他是一个类似于磨具的东西,可和object一样占用空间。在第二步的时候我们会看到static field的东西得到了初始化,所以说static 的东西是属于类对象而不是属于对象的。当.class第一次被导入的时候,被static修饰过的东西也随之allocate。所以我们能够有Class2.classField/Class2.classMethod的写法,这些东西是只占用一块内存空间的和new instance 没有任何关系。对于没有被static修饰过的field就属于instance field了,这个时候obj.classField/obj.classMethod的写法就产生了,他们和new instance 由某种惟妙惟肖的关系。
第三步:Definition initializaiont:这个时候程序会做一些定义初始化的动作,比如class类里面的field的初始化。
最后一步:Construction initialization:这个地球人都知道了,我就不说了。

下面是一个例子,看看是否和你的想象一样。
class Cup
{
Cup(int marker)
{
System.out.println("Cup(" + marker + ")");
}
void f(int marker)
{
System.out.println("f(" + marker + ")");
}
}
class Cups
{
static Cup c1=new Cup(1);
Cup c3=new Cup(3);
static Cup c2= new Cup(2);
Cups()
{
System.out.println("Cups()");
}
Cup c4=new Cup(4);
}
public class ExplicitStatic
{
Cups c=new Cups();
{
System.out.println("Hello");
}
public static void main(String[] args)
{
System.out.println("Inside main()");
Cups.c1.f(99);
ExplicitStatic x=new ExplicitStatic();
}
static Cups x = new Cups();
}

大家可以手动执行一下这个程序,考虑一下结果是什么,然后参照下面的答案对照一下,看看是否正确:
Cup(1)
Cup(2)
Cup(3)
Cup(4)
Cups()
Inside main()
f(99)
Cup(3)
Cup(4)
Cups()
Hello
因为Static是属于类对象的所以,只初始化一次。也正是因为Static是属于类对象的所以,先处理被Static修饰过的东西。

Plus:
class field:共用一块内存
class method:共用一块内存
instance field:随着每个instance各有一块内存
instance method:共用一块内存(_! why?)
JVM为了节省空间,所以
instance1.instanceMethod();
instance2.instanceMethod();
编译器会吧instance1和instance2作为instanceMethod()的一个隐藏的参数传入方法内(当然我们是看不到了)。这个东东就是我们常常说的this。用这种方法来区分是哪一个instance来调用方法,哎Gosling就是聪明。

看不太懂的说………………

执行new Instance之后进入构造函数。
Definition initializaiont是由Construction initialization调用的

可是为什么Definition initializaiont在Construction method之前被调用呢?