java中类加载顺序
执行父类的静态成员
执行子类的静态成员
父类的实例成员和实例初始化
执行父类的构造方法
子类的实例成员和实例初始化
子类的构造方法
第一题
package com.forcoldplay.javase;
public class Demo22 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Son son = new Son();
}
}
class Parent{
{
System.out.println("1");
}
static {
System.out.println("2");
}
public Parent(){
System.out.println("3");
}
}
class Son extends Parent{
{
System.out.println("4");
}
static {
System.out.println("5");
}
public Son(){
System.out.println("6");
}
}
输出结果为:2 5 1 3 4 6
执行父类的静态成员 2
执行子类的静态成员 5
父类的实例成员和实例初始化 1
执行父类的构造方法 3
子类的实例成员和实例初始化 4
子类的构造方法 6
第二题
我们改变一下静态代码块,实例成员和构造方法的顺序,结果依然不变
多个静态代码块,会根据顺序依次执行
package com.forcoldplay.javase;
public class Demo22 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Son son = new Son();
}
}
class Parent{
public Parent(){
System.out.println("3");
}
static {
System.out.println("2");
}
{
System.out.println("1");
}
}
class Son extends Parent{
public Son(){
System.out.println("6");
}
static {
System.out.println("5");
}
static {
System.out.println("7");
}
{
System.out.println("4");
}
}
输出结果为:2 5 1 3 4 6
第三题
package cn.forcoldplay.test1;
class X{
Y y = new Y();
public X() {
System.out.println("X");
}
}
class Y{
public Y() {
System.out.println("Y");
}
}
public class Z extends X{
//public class Z {
Y y = new Y();
public Z() {
System.out.println("Z");
}
public static void main(String[] args) {
new Z();
}
}
输出结果为 YXYZ
我们可以加入输出语句加深理解,尝试在每个字母输出前加个顺序
package cn.forcoldplay.test1;
class X{
//先执行父类的静态代码块,因为没有,则执行父类的静态成员和静态初始化
{
System.out.println("1");
}
Y y = new Y();
//输出2之后,会先执行父类的构造函数
public X() {
System.out.println("X");
}
{
System.out.println("2");
}
}
class Y{
public Y() {
System.out.println("Y");
}
}
public class Z extends X{
//执行完父类的构造函数之后,会执行子类的静态代码块,因为没有
//继续执行父类的静态成员和静态初始化
{
System.out.println("3");
}
Y y = new Y();
//最后会执行子类的构造方法
{
System.out.println("4");
}
public Z() {
System.out.println("Z");
}
public static void main(String[] args) {
//程序入口
new Z();
}
}
输出结果为 1Y2X3Y4Z