Java开发网 Java开发网
注册 | 登录 | 帮助 | 搜索 | 排行榜 | 发帖统计  

您没有登录

» Java开发网 » Java SE 综合讨论区 » Java与OOP初步  

按打印兼容模式打印这个话题 打印话题    把这个话题寄给朋友 寄给朋友    该主题的所有更新都将Email到你的邮箱 订阅主题
flat modethreaded modego to previous topicgo to next topicgo to back
作者 JAVA面试题解惑系列(一)——类的初始化顺序
臧圩人





发贴: 63
积分: 15
于 2008-06-26 09:56 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
原文地址:http://zangweiren.javaeye.com/blog/208122

作者:臧圩人
网址:http://zangweiren.javaeye.com

大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台的代码,然后让我们判断输出的结果。这实际上是在考查我们对于继承情况下类的初始化顺序的了解。

我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这一点:
Java代码
public class InitialOrderTest {

// 静态变量
public static String staticField = "静态变量";
// 变量
public String field = "变量";

// 静态初始化块
static {
System.out.println(staticField);
System.out.println("静态初始化块");
}

// 初始化块
{
System.out.println(field);
System.out.println("初始化块");
}

// 构造器
public InitialOrderTest() {
System.out.println("构造器");
}

public static void main(String[] args) {
new InitialOrderTest();
}
}

运行以上代码,我们会得到如下的输出结果:

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

这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果:
Java代码
class Parent {
// 静态变量
public static String p_StaticField = "父类--静态变量";
// 变量
public String p_Field = "父类--变量";

// 静态初始化块
static {
System.out.println(p_StaticField);
System.out.println("父类--静态初始化块");
}

// 初始化块
{
System.out.println(p_Field);
System.out.println("父类--初始化块");
}

// 构造器
public Parent() {
System.out.println("父类--构造器");
}
}

public class SubClass extends Parent {
// 静态变量
public static String s_StaticField = "子类--静态变量";
// 变量
public String s_Field = "子类--变量";
// 静态初始化块
static {
System.out.println(s_StaticField);
System.out.println("子类--静态初始化块");
}
// 初始化块
{
System.out.println(s_Field);
System.out.println("子类--初始化块");
}

// 构造器
public SubClass() {
System.out.println("子类--构造器");
}

// 程序入口
public static void main(String[] args) {
new SubClass();
}
}

运行一下上面的代码,结果马上呈现在我们的眼前:

父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器

现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。

那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。

同样,我们还是写一个类来进行测试:
Java代码
public class TestOrder {
// 静态变量
public static TestA a = new TestA();

// 静态初始化块
static {
System.out.println("静态初始化块");
}

// 静态变量
public static TestB b = new TestB();

public static void main(String[] args) {
new TestOrder();
}
}

class TestA {
public TestA() {
System.out.println("Test--A");
}
}

class TestB {
public TestB() {
System.out.println("Test--B");
}
}

运行上面的代码,会得到如下的结果:

Test--A
静态初始化块
Test--B

大家可以随意改变变量a、变量b以及静态初始化块的前后位置,就会发现输出结果随着它们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。

了解了继承情况下类的初始化顺序之后,如何判断最终输出结果就迎刃而解了。


臧圩人 edited on 2008-06-26 16:04

我的博客:http://zangweiren.javaeye.com
JAVA面试题解惑系列:http://zangweiren.javaeye.com/category/34977
作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
JiafanZhou



版主


发贴: 736
积分: 61
于 2008-06-26 15:59 user profilesend a private message to usersend email to JiafanZhousearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
臧圩人 wrote:
我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是静态变量>静态初始化块>变量>初始化块>构造器。

注意这句话是错的。*静态变量*,*静态初始化块* 初始化顺序是按照顺序的,也就是那个在前面哪个先初始化,而不是静态变量>静态初始化块。(变量>初始化块也是一样的道理)

臧圩人 wrote:
实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。

还有一点要注意的就是静态变量不能被继承。



When I was a kid I used to pray every night for a new bike. Then I realized that The Lord doesn't work that way, so I stole one and asked him to forgive me.
作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
臧圩人





发贴: 63
积分: 15
于 2008-06-26 16:07 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
感谢HenryShanley,关于第一处问题,在csdn也有网友提出来了,我已经做了修正。

第二处我想是你误解了我的意思,我并不是说静态变量可以继承,只是说明当父类和子类同时存在静态变量时,他们的初始化顺序。



我的博客:http://zangweiren.javaeye.com
JAVA面试题解惑系列:http://zangweiren.javaeye.com/category/34977
作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
JiafanZhou



版主


发贴: 736
积分: 61
于 2008-06-26 16:18 user profilesend a private message to usersend email to JiafanZhousearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
臧圩人 wrote:
第二处我想是你误解了我的意思,我并不是说静态变量可以继承,只是说明当父类和子类同时存在静态变量时,他们的初始化顺序。

Understood.



When I was a kid I used to pray every night for a new bike. Then I realized that The Lord doesn't work that way, so I stole one and asked him to forgive me.
作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
Joffeec





发贴: 47
积分: 3
于 2008-06-27 10:06 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
谢谢!!对类的初始化有了更深的理解了。


作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
臧圩人





发贴: 63
积分: 15
于 2008-06-27 11:35 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
呵呵,偶的这篇浅显的文章上了javaeye首页了,有点意外


我的博客:http://zangweiren.javaeye.com
JAVA面试题解惑系列:http://zangweiren.javaeye.com/category/34977
作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
JiafanZhou



版主


发贴: 736
积分: 61
于 2008-06-27 16:00 user profilesend a private message to usersend email to JiafanZhousearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
臧圩人 wrote:
呵呵,偶的这篇浅显的文章上了javaeye首页了,有点意外

Although this article seems a little simple, the advent of this article helps people who are new to Java greatly. So don't feel your work is disregarded. In light of Java development, I hope to see more articles like this from you in the future. That is why I dole out a point to you, good job.

Regards,
Jiafan



When I was a kid I used to pray every night for a new bike. Then I realized that The Lord doesn't work that way, so I stole one and asked him to forgive me.
作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
臧圩人





发贴: 63
积分: 15
于 2008-06-27 17:08 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
呵呵,谢谢楼上的鼓励和支持。


我的博客:http://zangweiren.javaeye.com
JAVA面试题解惑系列:http://zangweiren.javaeye.com/category/34977
作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
jancyu2008





发贴: 36
积分: 0
于 2008-07-01 21:27 user profilesend a private message to usersend email to jancyu2008search all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
臧圩人 wrote:
呵呵,偶的这篇浅显的文章上了javaeye首页了,有点意外

Hehe,加油哦



Every day thinking about JAVA, because I like to
Welcome to My pagehttp://jeakylau.51.com
My E-mail:jeakylau@126.com
My QQ : 529163539
作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
臧圩人





发贴: 63
积分: 15
于 2008-07-01 21:50 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
谢谢楼上的支持!


我的博客:http://zangweiren.javaeye.com
JAVA面试题解惑系列:http://zangweiren.javaeye.com/category/34977
作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
uriesijsif





发贴: 9
积分: 0
于 2008-07-23 20:35 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
对我很有帮助。。


作者 Re:JAVA面试题解惑系列(一)——类的初始化顺序 [Re:臧圩人]
liusiyu1468





发贴: 1
积分: 0
于 2008-10-03 16:27 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
good 受益匪浅




flat modethreaded modego to previous topicgo to next topicgo to back
  已读帖子
  新的帖子
  被删除的帖子
Jump to the top of page

   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923