java 初始化 顺序 疑惑?

小昭归来 发布于 2014/12/04 18:13
阅读 347
收藏 1

Java变量初始化顺序大体上应该是:先照静态按照顺序,再找非静态按照顺序初始化,然后再进入构造函数初始化

class Meal {
	public Meal() {
		System.out.println("meal");
	}
}

class Bread {
	int i;
	public Bread() {
		System.out.println("bread");
	}

	public Bread(int i) {
		this.i = i;
	}
}

class Cheese {
	public Cheese() {
		System.out.println("cheese");
	}
}

class Lettuce {
	public Lettuce() {
		System.out.println("lettuce");
	}
}

class Lunch extends Meal {
	public Lunch() {
		System.out.println("lunch");
	}
}

class PortableLunch extends Lunch {
	public PortableLunch() {
		System.out.println("portablelunch");
	}
}

class SandWich extends PortableLunch {
	private Bread b = new Bread();
	private Cheese c = new Cheese();
	private Lettuce l = new Lettuce();
	public SandWich() {
		System.out.println("sandwich");
	}
	
	public static void main(String[] args) {
		new SandWich();
	}
}

结果:

meal

lunch

portablelunch

bread

cheese

lettuce

sandwich

按照我的理解应该是:

bread

cheese

lettuce

meal

lunch

portablelunch

sandwich

我哪里出问题了呢


这下明白了,无论有没有继承,永远遵循这一条:非静态成员变量在构造方法执行前初始化。我犯的错误是:既然都进入到子类构造方法调用super()了,就认为构造方法执行,实际上是等父类都执行完了它才执行。额,想当然了。

加载中
0
红薯
红薯

你把程序执行一下不就一目了然了吗?

0
王爵nice
王爵nice
你把程序执行一下不就一目了然了吗?
0
小昭归来
小昭归来

引用来自“王爵”的评论

你把程序执行一下不就一目了然了吗?
顺序是这样但是为啥子呢


class Bird {
public Bird(int i) {
System.out.println(i+"只头的鸟");
}
}


class Parrot {
Bird bird1 = new Bird(1);
Bird bird2 = new Bird(2);
public Parrot() {
System.out.println("鹦鹉呢");
}
Bird bird3 = new Bird(3);
static Bird bird4 = new Bird(4);
}


这样new Parrot结果就是
4只头的鸟
1只头的鸟
2只头的鸟
3只头的鸟
鹦鹉呢
为啥上面那个不是呢
0
battyman
battyman

有继承的:

main方法开始 > 子类对象的初始化语句 > 子类构造(先不执行) > 父类构造(先不执行) >父类静态变量 > 子类静态变量 > 初始化父类变量(按顺序) > 父类构造 > 子类变量初始初始(按顺序) > 子类构造 > 运行main后的语句 > 程序结束


没有继承的:

静态变量 > 静态初始化块 > 变量 > 初始化块 > 构造器

0
小昭归来
小昭归来

引用来自“battyman”的评论

有继承的:

main方法开始 > 子类对象的初始化语句 > 子类构造(先不执行) > 父类构造(先不执行) >父类静态变量 > 子类静态变量 > 初始化父类变量(按顺序) > 父类构造 > 子类变量初始初始(按顺序) > 子类构造 > 运行main后的语句 > 程序结束


没有继承的:

静态变量 > 静态初始化块 > 变量 > 初始化块 > 构造器

class SandWich extends PortableLunch {
    private Bread b = new Bread();
    private Cheese c = new Cheese();
    private Lettuce l = new Lettuce();
    public SandWich() {
        System.out.println("sandwich");
    }
     
    public static void main(String[] args) {
        new SandWich();
    }

}

父类构造 > 子类变量初始初始(按顺序) > 子类构造 按照您这个说法,当父类初始化完成之后,应该依次初始化Bread Cheese 和 Lettuce然后才是子类的构造函数呀吧,但打印顺序不是呢



0
Shazi199
Shazi199

首先你这里没有静态的东西,那么事情就很好办了。

1.执行main方法,遇到 new SanWich(),那么就开始从SanWich最顶级的父类开始初始化。

    所以有meal lunch portablelunch

2.初始化SanWich的私有成员变量

    所以有bread cheese lettuce

3.执行SanWich的构造方法

    所以有sandwich

小昭归来
小昭归来
这下明白了,无论有没有继承,永远遵循这一条:非静态成员变量在构造方法执行前初始化。我犯的错误是:既然都进入到子类构造方法调用super()了,就认为构造方法执行,实际上是等父类都执行完了它才执行。额,想当然了。
0
sscust
sscust
其实你只要明白一点,你就完全懂了,那就是父类costructor先于子类的Constructor中的第一句执行就OK了,也就是super()肯定是当前contructor类中默认第一个语句,不信,你可以把super()写在contructor的第二句、第三句试试,立马报错
0
Candy_Desire
Candy_Desire
先执行父类的构造方法,然后再执行子类的不解释!
返回顶部
顶部