父类
package test;
public class Parent {
public static int a=2;
{
System.out.println("父类非静态代码块");
}
static{
System.out.println("父类静态代码块");
}
public static void name1() {
System.out.println("父类静态方法1");
}
public static int name2() {
System.out.println("父类静态方法2");
return 9;
}
public void getName() {
System.out.println("父类实例方法");
}
public Parent() {
System.out.println("父类构造方法");
}
@Override
protected void finalize() throws Throwable {
System.out.println("Parent finalize by itself");
}
}
子类
package test;
public class Child extends Parent {
private int a=getChildName();
{
System.out.println("子类非静态代码块");
}
static{
System.out.println("子类静态代码块");
}
public static void childNname1() {
System.out.println("子类静态方法1");
}
public static int childName2() {
System.out.println("子类静态方法2");
return 9;
}
public int getChildName() {
System.out.println("子类实例方法");
return 2;
}
public Child() {
System.out.println("子类构造方法");
}
@Override
protected void finalize() throws Throwable {
//super.finalize();
System.out.println("Son finalize by itself");
//Float.floatToIntBits("");
}
}
1. 第一种情况(父类静态成员变量a直接赋值2)
package test;
public class Test {
public static void main(String[] args) {
int a=Parent.a;
}
}
结果:
父类静态代码块
2. 第二种情况(父类静态成员变量a通过静态方法赋值)
父类代码改为:
public static int a=name2();
package test;
public class Test {
public static void main(String[] args) {
int a=Parent.a;
}
}
结果:
父类静态方法2
父类静态代码块
3. 第三种情况(测试实例化一个Parent)
父类代码复原:
public static int a=2;
package test;
public class Test {
public static void main(String[] args) {
Parent parent=new Parent();
}
}
结果:
父类静态代码块
父类非静态代码块
父类构造方法
4. 第四种情况(测试实例化一个Child)
package test;
public class Test {
public static void main(String[] args) {
Child child =new Child();
}
}
结果:
父类静态代码块
子类静态代码块
父类非静态代码块
父类构造方法
子类非静态代码块
子类构造方法
结论
不管是静态方法还是实例化方法,只有在调用的时候才会执行。
类加载的时候只有静态代码块和静态成员变量进会行初始化。
类实例化时执行顺序为:先初始化父类和子类的静态代码块、静态成员变量(顺序从上往下执行),父类非静态代码块和普通成员变量(顺序从上往下)、父类构造方法,子类非静态代码块和普通成员变量(顺序从上往下执行)、子类构造方法。