先上代码:
package newcode;
public class granpa {
public static int age;
public int level;
public granpa() {
age=80;
level=3;
System.out.println("爷爷的构造函数");
System.out.println("level="+level+",age="+age);
}
static {
System.out.println("爷爷的静态块");
System.out.println(",age="+age);
}
{
System.out.println("爷爷的构造块");
System.out.println("level="+level+",age="+age);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package newcode;
public class dad extends granpa {
public static int age;
public int level;
public dad() {
level=2;
age=50;
System.out.println("爸爸的构造函数");
System.out.println("level="+level+",age="+age);
}
static {
System.out.println("爸爸的静态块");
System.out.println(",age="+age);
}
{
System.out.println("爸爸的构造块");
System.out.println("level="+level+",age="+age);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package newcode;
public class me extends dad{
public static int age;
public int level;
public me() {
level=1;
age=20;
System.out.println("我的构造函数");
System.out.println("level="+level+",age="+age);
}
static {
System.out.println("我的静态块");
System.out.println(",age="+age);
}
{
System.out.println("level="+level+",age="+age);
System.out.println("我的构造块");
}
public static void main(String[] args) {
new me();
// TODO Auto-generated method stub
}
}
结果:
爷爷的静态块
,age=0
爸爸的静态块
,age=0
我的静态块
,age=0
爷爷的构造块
level=0,age=0
爷爷的构造函数
level=3,age=80
爸爸的构造块
level=0,age=0
爸爸的构造函数
level=2,age=50
我的构造块
level=0,age=0
我的构造函数
level=1,age=20
总结:
- 首先初始化父类的静态成员变量和静态代码块,按照在程序中出现的顺序初始化
- 然后初始化子类的静态成员变量和静态代码块,按照在程序中出现的顺序初始化
- 其次初始化父类的普通成员变量和代码块,再执行父类的构造方法
- 最后初始化子类的普通成员变量和代码块,再执行子类的构造方法
- 还有注意:granpa g=new me();左边为编译,右边为运行。
- 用this()可以再构造器中调用构造器
再举一个例子,牛客中的一道题:
package newcode;
public class Test {
static class A{
protected int value;
public A(int v) {
setValue(v);
}
public void setValue(int value) {
this.value=value;
}
public int getValue() {
try {
value++;
return value;
}
catch(Exception e) {
System.out.println(e.toString());
}
finally {
this.setValue(value);
System.out.println(value);
}
return value;
}
}
static class B extends A{
public B() {
super(5);
setValue(getValue()-3);
}
public void setValue(int value) {
super.setValue(2*value);
}
}
public static void main(String[] args) {
System.out.println(new B().getValue());
// TODO Auto-generated method stub
}
}
输出结果:
22
34
17
题中注意要点:
- 有finally模块时,try{ }中已经return了,所以这个方法的返回值级已经保存下来了,题中是11,即使finally{ }里面又对value的值做出了改变,变成22,但是getValue()的返回值是不会变的。
- 注意运行时,先调用近的方法,没有再到父类中找,如果要指定调用父类的某个方法,要有super.method()来调用。