**#Example 1#
class X{
Y y = new Y();
public X(){
System.out.println("X");
}
}
class Y{
public Y(){
System.out.println("Y");
}
}
class Z extends X{
Y y = new Y();
public Z(){
System.out.println("Z");
}
public static void main(String[] args) {
new Z();
}
}
-
初始化父类中的静态变量和静态代码块
-
初始化子类中的静态变量和静态代码块
-
初始化父类中的普通成员变量和代码块(初始化代码块Y y = new Y());再执行父类的构造方法( public X (){} )
先执行父类的代码块(初始化代码块) Y y = new Y();
一般在new()对象时,系统会自动调用构造方法!!!
public Y (){ Syso("Y"); }
再执行父类的构造方法
public X(){ Syso("X") }
-
初始化子类中的普通成员变量和代码块(初始化代码块);再执行子类的构造方法(类的构造方法)
Y y = new Y()
系统自动调用构造方法!!!
public Y(){ Syso("Y"); }
再执行子类的构造方法
public Z(){ Syso("Z"); }
最终输出为: YXYZ
**#Example 2#
public class Base{
private String baseName = "base";
public Base(){
callName();
}
public void callName(){
System.out.println(baseName);
}
static class Sub extends Base{
private String baseName = "sub";
public void callName(){
System.out.println("baseName");
}
public static void main(String[] args) {
Base b = new Sub();
}
}
}
-
初始化父类的静态变量和静态代码块
父类无静态变量和静态代码块
-
初始化子类的静态变量和静态代码块
子类有静态代码块main方法,进入执行。
Base b = new Sub();
-
初始化父类的普通成员变量和代码块(初始化代码块), 再执行父类的构造方法(类的构造)。
private String baseName = "base";
初始代码块相当于多态调用
再执行父类的构造方法(类的构造)
public Base(){ callName(); }
-
成员方法,编译看父类,运行看子类
callName()编译看父类的callName()方法,运行看子类的callName()方法
public void call(){ System.out.println(baseName); }
此时关于变量的使用规则是:
子类有,就用子类的,不用户父类的变量。
方法内用,就用方法内的,不要成员变量。
所以
用子类的baseName变量,但是要等到父类的构造方法执行结束才能执行初始化子类的成员变量(private String baseName = “sub”)和子类代码块等一系列操作
所以
String baseName = null; 所以最终的输出是null
-
初始化子类的普通成员变量和代码块,再执行子类的构造方法
-
private String baseName = "sub"; ······
**#Example 3#
类方法中不可以直接调用对象变量
这是因为,静态方法在类加载时就初始化了,对象变量需要在新建对象后才能使用