3
class a
{
a(){System.out.println("A");}
}

class b extends a
{
b()
{
super();
System.out.println("B");}
}

class c extends b
{
c(){System.out.println("c");}
}

class last
{
public static void main(String aaa[])
{
c obj = new c();
}
}

输出如下:

一个

C

不应该是:

一个

一个

C

因为 super 关键字

4

5 回答 5

8

super();如果您未明确指定,则始终存在。如果您没有明确指定,Java 只会添加自动调用。

所以你的代码

    B() {
        super();
        System.out.println("B");
    }

    B() {
        System.out.println("B");
    }
于 2012-10-15T07:33:25.983 回答
4

不。如果您super在构造函数中调用,则不会添加自动调用。如果您不使用,编译器只会添加自动调用。因此super();in 行b是不必要的,因为这正是编译器将为您添加的内容(对默认构造函数的调用)。也就是说,这两位源代码产生相同的字节码:

// This
class b {
    b() {
    }
}

// Results in the same bytecode as this
class b {
    b() {
        super();
    }
}

能够直接调用超类构造函数的原因是为了向它传递参数,因为编译器只会添加对默认构造函数的调用(如果超类上没有调用,则会报错)。

于 2012-10-15T07:33:12.093 回答
2

super();通过继承树在任何构造函数中调用一次,无论是显式执行还是隐式执行。所以你不应该期望“A”会被打印两次。

这不会编译:

b()
{
    super();
    super();
    System.out.println("B");
}

错误消息: 构造函数必须是构造函数中的第一条语句。

这意味着您不允许super()在构造函数中多次调用。

于 2012-10-15T07:35:56.310 回答
0

如果您使用 extends 关键字创建其他类的子类,那么 java 编译器会将super()调用作为构造函数的第一行(以防您自己没有这样做)。在您的示例中,类a扩展(默认情况下)java.lang.Object()并在编译后第一行是 call super(),它调用Object默认构造函数。所以在运行子类构造函数中的代码之前,运行其超类构造函数中的代码。

为什么A没有打印多次?因为 Java 编译器只有在你自己没有这样做的情况下才会在构造函数的开头添加super() 。(例如,您可能想调用接受某些参数的超类构造函数)

希望这能澄清一点。

于 2012-10-15T07:40:51.780 回答
0
package threaddemo;

public class NewClass {
    NewClass() {
        System.out.println("hello");
    }
}

class Child extends NewClass {

    Child() {
        System.out.println("child");
    }

    public static void main(String []ar) {
        Child c1=new Child();
    }
}
于 2014-06-05T19:32:09.093 回答