A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 烟花雨 中级黑马   /  2013-10-23 21:21  /  1395 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

为什么super(…)和this(…)调用语句不能同时在一个构造函数中出现?知道的请解答下...

4 个回复

正序浏览
本帖最后由 我能学编程吗 于 2013-10-24 01:01 编辑

我个人简单分析如下:
new一个对象时,要先存在父类,现实中也就是要先有爸爸才有儿子。
所以new一个对象时,子类都要调用父类的构造函数,意思是先让爸爸先出来,爸爸又有爸爸,又得调用super(),最终是调用到Object的构造器,也就是说Object是最先出来的,然后是它的儿子出来,然后是儿子的儿子出来。。。

好了,有了以上原理,那们我们就知道了,所有的构造器都是用来创建对象的,那么在创建对象的第一行,一般都是会用super()调用父类,如果你不写的话Java会自动加上。如下:
class Child extends Parent {
        public Child() {
                super();
        }
        
        public Child(int i) {
                super();
        }
}


那为什么this可以放在第一句,如下:
class Child extends Parent {
        public Child() {
                super(); // 如果不写默认会加上
        }
        
        public Child(int i) {
                this(); // 如果写了this,第一行就不会默认加上super()了
        }
}

上面代码最张会调用这个构造函数:public Child() ,从代码可知,这里会调用super();  那么此时父类又会调用super。。。一直把所有的爸爸都搞出来为止,然后自己才出来。

那为什么this与super不同同时出现?如下:
class Child extends Parent {
        public Child() {
                super();
        }
        
        public Child(int i) {
                this();    // 将会调用public Child() ,那么Child() 中的super将会执行,父类也会调用super。。。一直把所有的爸爸都搞出来
                super(); // 父类也会调用super。。。一直把所有的爸爸都搞出来
        }
}


从上面分析,爸爸要搞出来两次,不合理吧!所以为什么this()与super()不能同时出现,希望能明白!


评分

参与人数 1技术分 +1 收起 理由
周志龙 + 1 赞一个!

查看全部评分

回复 使用道具 举报
  1. class A
  2. {
  3.         A()
  4.         {
  5.           System.out.println("a");
  6.         }
  7. }
  8. class B extends A
  9. {
  10.         private String work;
  11.         B()
  12.         {
  13.                 super();  // 当去掉super()后和不去它,结果都是一样的,所以super()是隐式,那么如果下面的构造函数中在显式调用super(),那么将重复,所以我觉得这个大概是原因。
  14.                 System.out.println("B1");   
  15.         }
  16.         B(String work)
  17.         {
  18.            this();          
  19.            this.work=work;
  20.            System.out.println(this.work);
  21.         }
  22. }
  23. class Test1
  24. {
  25.         public static void main(String[] args)
  26.         {
  27.        new B("teacher");       
  28.         }
  29. }
复制代码
Test1.java:18: 错误: 对this的调用必须是构造器中的第一个语句
           this();
Test1.java:13: 错误: 对super的调用必须是构造器中的第一个语句
           super();
        经过代码验证,jvm规定  super()  和 this()  都必须在构造函数中第一句

评分

参与人数 1技术分 +1 收起 理由
杨增坤 + 1

查看全部评分

回复 使用道具 举报
我想这应该是java构造函数的一种机制吧,首先以子类和父类为例。
当你创建一个子类的实例时,首先会调用父类的构造函数,然后再调用子类的构造函数,如果父类中没有缺省构造函数,则必须再子类的构造函数中显示的调用它(如下面的例子),
在程序中的顺序是这样的:
         
                 super(...) //父类构造函数
                  .....        //当前类构造函数语句
同样的道理,当一个类中有多个构造函数的时候,在其中一个构造函数中也可以先调用其他的构造函数来初始化对象,这种方法叫做“显式构造方法调用”,当那样的构造方法被调用,它将执行通常的super() 过程以及后续的操作。然后在执行本构造函数中的构造语句,这个时候的顺序是这样的:
                  this(....)     //当前类的其他构造函数
                  ...         //当前构造函数的其他语句

其实为什么要把this(...)放在前面很容易理解,因为任何的子类都必须要先调用父类的构造函数,而当你采用“显示构造方法调用”即用this(...)调用当前类的其他构造函数时,这个时候父类的构造就在this(...)里面执行了,this(...)里面应该不仅包括当前类的构造,还必须包括父类的构造,所以为了保证父类的构造函数先被执行,必须要先调用this(.....)

评分

参与人数 1技术分 +1 收起 理由
李江 + 1 很给力!

查看全部评分

回复 使用道具 举报
语法要求,因为这两个都要求写在首行。另外这两个都是语句,不可能写成super(),this();
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马