父类A
public class A {
{
System.out.println("父类构造代码块");
}
static{
System.out.println("父类静态代码块");
}
public A() {
System.out.println("父类无参构造");
}
}
子类B
public class B extends A{
int b=2;
{
System.out.println("子类构造代码块");
}
static{
System.out.println("子类静态代码块");
}
public B() {
System.out.println("子类无参构造");
}
public B(int b) {
super();
this.b = b;
System.out.println("子类有参构造");
}
}
创建父类对象
public static void main(String[] args) {
new A();
}
执行后结果
父类静态代码块
父类构造代码块
父类无参构造
由此执行结果可以看出java中的执行顺序是静态代码块,构造代码块,构造方法
再创建子类对象
public static void main(String[] args) {
new B();
}
执行结果
父类静态代码块
子类静态代码块
父类构造代码块
父类无参构造
子类构造代码块
子类无参构造
虚拟机内部定义了两个方法clinit和init方法,clinit是对类的初始化,先初始化父类静态,然后子类静态,init是对实例的初始化,初始化父类构造器,然后子类构造器,所以执行结果如此
public class StaticTest {
static StaticTest st = new StaticTest();
static {
System.out.println("1");
}
{
System.out.println("2");
}
StaticTest() {
System.out.println("3");
System.out.println("a=" + a + ",b=" + b);
}
public static void staticFunction() {
System.out.println("4");
}
int a = 110;
static int b = 112;
public static void main(String[] args) {
staticFunction();
}
}
输出结果
2
3
a=110,b=0
1
4
静态成员变量最先执行 谁先执行看顺序
然后静态代码块按顺序执行
这里先静态对象,在构造方法前先执行构造代码块所以输出2
执行构造方法前成员变量a为110,而 static int b = 112没有被调用所以b为0
再执行静态代码块输出1
再执行staticFunction()方法
父类
public class APlus {
static int a = 200;
public APlus() {
System.out.println("父类构造方法");
add();
}
public void add() {
System.out.println("父类add方法");
System.out.println(a);
}
}
子类
public class BPlus extends APlus {
int a = 100;
public BPlus() {
super();
System.out.println("子类构造方法");
System.out.println(a);
}
public void add() {
System.out.println("重写了父类的add");
System.out.println(a);
}
}
创建子类对象
public static void main(String[] args) {
new BPlus();
}
执行结果
父类构造方法
重写了父类的add
0
子类构方法
100
父类静态变量a声明
父类构造器,执行add方法,这里是在实例化子类对象,所以这里是子类调用add方法,因为子类重写了父类的add方法,子类中的a还没有赋值,所以a为默认值0
子类构造器前子类成员变量a为100