日期:2014-05-20  浏览次数:20692 次

//各位,哪位又能解释得清楚这个问题呢,个人认为JAVA语言规划得并不是很合理!
public   class   aa
{
aa()
{ this( "renqiang ");
System.out.println( "aa类的第一个构造方法 ");
}
aa(String   s)
{
System.out.println( "aa类的第二个构造方法 ");
}
}
class   bb   extends   aa  
{
bb()
{ //super();
this( "temp ");

System.out.println( "bb类的第一个构造方法 ");
}
bb(String   b)
{
System.out.println( "bb类的第二个构造方法 ");
}
public   static   void   main(String   args[])
{
bb   t=new   bb();
}
}

/*********************************************************************
我的目的是按照以下的顺序输出如下:
aa类的第二个构造方法

aa类的第一个构造方法

bb类的第二个构造方法

bb类的第一个构造方法

但是如果不注释super();的话,则会提示this必须放在constructor的第一句.
让人费解的是.如果注释super();的话,系统还是会默认的会把super()加上来调用
其父类的构造函数的.这样一来,this还不是放在第二句了吗?(即不是放在constructor
的第一句)但是系统此时却又不提示出错了,则正常的运行.如上面所输出的.
哪位能解释的清楚呢?

*********************************************************************/

------解决方案--------------------
class bb extends aa
{
bb()
{ this( "temp ");


System.out.println( "bb类的第一个构造方法 ");
}
bb(String b)
{super();


System.out.println( "bb类的第二个构造方法 ");
}
public static void main(String args[])
{
bb t=new bb();
}
}
------解决方案--------------------
编译的时候“提示this必须放在constructor的第一句”的目的在于,子类在构造过程中,如果要引用另一个构造方法,必须在“其它执行语句”的前面。而这里的“其它执行语句”,指的是子类里写的某些语句,不包括“父类里的语句”。事实上,父类的构造方法*一定*是要被首先调用的(无论是隐式的还是显式的)。

这正是 Java 语法“严格”的表现,基本上可以说,你找不到它“不恰当”的地方 ;)
------解决方案--------------------
调用重载的构造函数只能调用一次,而且必须放到构造函数的第一句,由于你使用的是BB无参构造方法,所以SUPER是不必须写的,默认调用SUPER
------解决方案--------------------
自己不理解别这么冒失地发表你的慷慨激词!!
------解决方案--------------------
道理很简单,除了java.lang.Object之外的任意一个类(像上面的aa,bb),
只要aa或bb类的源码中定义了构造方法,且构造方法的第一条语句
不是“this(可选参数)”或“super(可选参数)”调用,
编译器都会默认产生一条super()语句,作为这个构造方法的第一条语句。

这样做的目的就是保证初始化子类前,所有父类都已正确初始化。

因为你是通过bb t=new bb()开始的,
所以先调用bb()构造方法,因bb()构造方法第一条语句是this( "temp ");
所以编译器不会为bb()构造方法产生super()语句,JVM接着不会调用
aa类的构造方法,而是转到bb(String b),因bb(String b)内部第一条
语句不是“this(可选参数)”或“super(可选参数)”调用,所以编译器
已为它产生了一条super()语句,JVM接着调用aa(),再到aa(String s),
再到java.lang.Object的Object()调用结束。
所以结果就是:

aa类的第二个构造方法
aa类的第一个构造方法
bb类的第二个构造方法
bb类的第一个构造方法

另外“this(可选参数)”或“super(可选参数)”语句只能出现在最前面,
只能二选一,这是语言规范,没什么好解释的。


有不明白的地方用javap -verbose bb看看字节码或者看看javac的源码
在com.sun.tools.javac.comp.MemberEnter类有点说明
------解决方案--------------------
楼上的朋友,首先谢谢你这这么详细的给我讲解.
但是您所说的: "因bb(String b)内部第一条
语句不是“this(可选参数)”或“super(可选参数)”调用,所以编译器
已为它产生了一条super()语句 "如果这样的话,在产生了一条super()语句之后
那么他后面的语句就不执行了吗?也就是说bb(String b)内还有这样一句话: "System.out.println( "bb类的第二个构造方法 "); ".如果不是的话,而且照你所说的流程的话.输出的第一句话应该是:

"bb类的第二个构造方法 "才对啊?
------解决方案--------------------
我认为这个问题是这样的:this()用来指明调用本类的重载构造方法, 在那里也是会有super的,所以就没必要在本方法中写了呵呵,对不对?