这里主要验证两个问题:
1 静态区域 块 动态区域 块 构造函数 的执行顺序
2 初始化的时候和赋值语句的先后顺应是否有关。就是 是不是初始化的时候先为0后又执行赋值语句。
这些东西都是记忆性的东西,但是如果弄错顺序就会搞出错误。所以,没办法,我得记住。
父类静态块
子类静态块
父类动态块
父类构造方法
子类动态块
子类构造方法
结论:
先静态 后动态
先父类 后子类
先动态块后构造方法。
代码:
public class ad
{
public ad(){
System.out.println("父类构造方法");
}
static {
System.out.println("父类静态块");
}
{
System.out.println("父类动态块");
}
public static void main(String[] args)
{
b b1=new b();
}
}
class b extends ad{
public b(){
System.out.println("子类构造方法");
}
{
System.out.println("子类动态块");
}
static {
System.out.println("子类静态块");
}
}
至于网上有人说先初始化为默认值,然后在顺序赋值。这个等会吧。
还有好多相关问题需要验证,等碰到了,再加吧,懒了,心碎了。
下面是别人总结好的,确实很全。但我没有验证
通过对输出进行分析,可以得出如下结果:1、在类第一次加载时候,会执行静态域(field)初始化语句和静态块(用static{}包含的部分)。这里要注意: a、不管静态域声明语句的实际位置在哪儿,当第一次加载类的时候都会首先对它初始化为缺省值(0,false,null等)。b、即使静态域声明中使用了显式初始化语句(比如:intx=3),第一次加载类的时候也会先把它初始化为缺省值(此时x为0),然后再按照下面说的要点c来执行赋值语句(x=3)。c、对于静态域的显式初始化语句和静态块,按照在类中代码出现的先后顺序执行。因此,在上面的例子程序中,我们看到 static int s_a=1;
static
{
s_a=11;
s_b=22;
}
static int s_b=2;对s_a,s_b会有不同的效果。类加载时候,s_a,s_b都被初始化为0,然后由于依照代码顺序执行了s_a=1;s_a=11;s_b=22;s_b=2;结果s_a、s_b分别变成了11和2。2、当构造类实例时候,会先对实例域初始化为缺省值,然后执行实例块(用{}括起来的部分),然后执行构造方法。其中:a、如同1中一样,如果有实例域的显式初始化语句,程序仍然是先将该域初始化为缺省值,然后按照代码在类中出现的先后顺序执行初始化语句或者实例块。如果实例块位置在初始化语句前面,即使它改变了该域的值,也会被随后执行的初始化语句改回去。b、在进入构造方法后,如果构造方法第一句是使用this(...)调用另一构造方法的话,则先执行另一构造方法,然后再执行本构造方法的方法体。这种用法必须让this(...)位于第一句。《Corejava2》书中所说的"进入构造方法后,如果第一句是调用别的构造方法,则进入别的构造方法。否则,执行实例块"的提法有问题。事实是,不管是否使用this()都会先执行实例块,再进入构造方法。另外,本程序需要在sdk1.4下编译,在sdk1.3下编译将不允许在静态块或实例块中改变位置在它们后面声明的域的值。