高手请进:类中奇怪的大括号 和 类实例初始化顺序?

biti509 2007-01-08 09:49:04
我找到个有趣的例子,自己改了改
有两个问题百思不得其解,高手指点
public class Base {
int i = 10;
{
System.out.println("Base:"+i);
//问题1:这是什么用法???,i需要在{}之前定义,否则出错,上句什么时候执行?
}
Base(int x){
f();
}
void f(){System.out.println("Base f "+i);}
}

public class BSub extends Base{
int i = 30;
public BSub() {
super(1);//实际调用的方法f是子类的f
}
void f(){System.out.println("BSub f "+i);}
//问题2:打印的i是0,这是子类还是父类的i?
//这里类实例化的顺序到底是怎样的??
public static void main(String[] args){
new BSub();
}
}
...全文
540 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
biti509 2007-01-09
  • 打赏
  • 举报
回复
还有一个问题,new子类的时候是否会产生一个父类对象,然后用super引用
biti509 2007-01-09
  • 打赏
  • 举报
回复
是不是可以这样理解super,不对请指出

子类构造函数第一句肯定会调super,但是super不能看作是一般的函数调用,返回后执行super下一句。比如当new子类的时候,先显式初始化父类变量,父类构造函数,不能这么认为是在执行子类构造函数中的super语句。对吗?

而是将super看作一个标识,表示父类要执行哪个构造函数


但实际new子类的时候后台根据super标示,执行顺序如下:
父类显式初始化变量-父类构造函数-子类显式初始化变量-子类构造函数
dracularking 2007-01-08
  • 打赏
  • 举报
回复
回biti509()
“请注意以下,父类的变量(显示赋值的)在其构造函数执行前已经就初始化了,怎么解释?”

这里之所以“搞”,就是因为子类构造函数中多了个super(),这个super()比较特殊,看似是经由子类的构造函数调用的,实则不完全是或者说不是,我那句犯了个错误,我想说明的一个顺序是 父类显式初始化-父类构造函数-子类显式初始化-子类构造函数,有下程序可证:

class Base
{
int i = 10;
{
System.out.println("Base:" + i);
}

Base(int x)
{
System.out.println("father's constructor x="+1);
f();
}

void f()
{
System.out.println("Base f " + i);
}
}

public class Test extends Base
{
int i = 30;

{
System.out.println("Test:" + i);
}

public Test()
{
super(1);
System.out.println("son's Test");
}

void f()
{
System.out.println("BSub f " + i);
}

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

z_lping 2007-01-08
  • 打赏
  • 举报
回复
哈哈哈哈,这句话好形象呀!
luhao 2007-01-08
  • 打赏
  • 举报
回复
先调用父类的构造函数,完了以后再进行自身的运行

说的通俗一点,先照顾好,孝敬好老人, 自己再管自己的事
z_lping 2007-01-08
  • 打赏
  • 举报
回复
父类变量初始化其实也是其构造函数运行的一部分。

构造函数的第一个print是在变量初始化之后才运行的。
z_lping 2007-01-08
  • 打赏
  • 举报
回复
super()是绝对的第一个运行的,也就是说,在初始化本类的变量之前,就运行了super。而运行super的时候,父类的变量就被初始化了。

程序可以随便改,加入需要的print语句,来了解运行次序。
biti509 2007-01-08
  • 打赏
  • 举报
回复
请注意以下,父类的变量(显示赋值的)在其构造函数执行前已经就初始化了,怎么解释?
dracularking 2007-01-08
  • 打赏
  • 举报
回复
因为在BSub执行其构造函数时,还没有轮到变量初始化,i当然就是0了
lz加几句测试就知道了
biti509 2007-01-08
  • 打赏
  • 举报
回复
super只是简单执行一下父类的构造函数吗?
biti509 2007-01-08
  • 打赏
  • 举报
回复
所以我一直想搞清楚new子类时,其中super的执行时应该会产生一个父类对象吗?
然后父类子类显式初始化的变量被赋初值,和构造函数之间的顺序到底如何?

父类子类显式初始化的变量被赋初值,构造函数,super的关系,还有初始化时我们看不到的地方java还在后台做了些什么,顺序怎样,这些并没有完全反应在程序的打印语句中

以上全是个人感觉
z_lping 2007-01-08
  • 打赏
  • 举报
回复
在super()返回之前,子类中的i还没有被付值呢。
biti509 2007-01-08
  • 打赏
  • 举报
回复
我自己认为的顺序是这样的,不知对不对,反正觉得很奇怪

如果是这样,
先是Base显式初始化的变量i被赋初值,然后执行Base的构造函数
那么子类BSub在执行其构造函数时,BSub中显式初始化的变量i应该也有初始值30了

但是执行Base的构造函数中的f时,打印子类BSub中的i却是0,这如何解释??
tddlhl 2007-01-08
  • 打赏
  • 举报
回复
我已经搞明白了,调用super只调用父类的构造函数,然后又因为虚函数的因素调用了子类的fn方法,而子类的变量在父类中没有初始化,所以为默认的0,所以得到以上的结果。
z_lping 2007-01-08
  • 打赏
  • 举报
回复
class Base {
int i = 10;
{
System.out.println("Base:"+i);
//问题1:这是什么用法???,i需要在{}之前定义,否则出错,上句什么时候执行?
}
Base(int x){
System.out.println("Enter Base Constructor " + i);
f();
System.out.println("After Base f() " + i);
}
void f(){System.out.println("Base f "+i);}
}

public class BSub extends Base{
int i = 30;
public BSub() {
super(1);//实际调用的方法f是子类的f
System.out.println("After BSub super(1) " + i);
}
void f(){System.out.println("BSub f "+i);}
//问题2:打印的i是0,这是子类还是父类的i?
//这里类实例化的顺序到底是怎样的??
public static void main(String[] args){
BSub bsub = new BSub();
System.out.println("After new BSub() " + bsub.i);
}
}
------------------------------------
简单的这样看一下运行次序吧。
----------------------------------------
Base:10
Enter Base Constructor 10
BSub f 0
After Base f() 10
After BSub super(1) 30
After new BSub() 30
------------------------------------
tddlhl 2007-01-08
  • 打赏
  • 举报
回复
为什么加了super后就不构造父类了?如果没有super的调用应该是先构造父类再构造子类呀
biti509 2007-01-08
  • 打赏
  • 举报
回复
但是在子类中的i已经显式初始化过了,是30

new子类的时候完整的执行顺序是什么啊??
安吉 2007-01-08
  • 打赏
  • 举报
回复
因为还没有显示初始化,所以打印默认值0,没错是这样,
现在明白没有
安吉 2007-01-08
  • 打赏
  • 举报
回复
问题2:打印的i是0,这是子类的i
这是覆盖,子类的方法覆盖父类的方法
zzwh_0 2007-01-08
  • 打赏
  • 举报
回复
问题1:初始化块,i需要在{}之前定义是因为f方法用到了这个i
问题2:子类的i ,因为还没有显示初始化,所以打印默认值0
加载更多回复(2)

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧