5

在这段代码中,我知道它可以与 A 类中的 super(t) 或 B 类中的无参数构造函数一起使用。下面的代码使用 B 类中的无参数构造函数。我知道如果你去掉无参数构造函数B类的代码不起作用。我是编程新手,我想了解的是 B 类中的无参数构造函数有什么特别之处,为什么代码必须存在才能工作?有什么特殊条件或规则?

public class Test {

    public static void main(String[] args) {

       B b = new B(5);

    }
}

class A extends B {
    public A(int t)  {

        System.out.println("A's constructor is invoked");
    }
}

class B  {

    public B() {

    }

    public B(int k)   {
    System.out.println("B's constructor is invoked");
    }
}
4

7 回答 7

2
class A extends B {

编译器确保在编译此类时;如果程序员没有编写this()super()明确地编写,它将super()在 class 中提供的每个构造函数中添加为第一行A

如果程序员没有提供其他构造函数,编译器还确保向类添加无参数构造函数。

现在,假设您没有在类中提供无参数构造函数B,编译器也不会提供,因为您提供了带参数的构造函数。但是,在类中A,它将super()作为构造函数中的第一行添加。即对基类无参数构造函数的调用。因此,它会导致编译器错误。

因此,正如您所说,要么在 class 中提供无参数构造函数,要么在 class中B编写。super(<int>)A

于 2013-01-10T06:29:06.207 回答
1

如果您定义任何其他构造函数,Java 将不会添加无参数构造函数。
没有参数构造函数是 Java 在需要时使用的默认构造函数。

于 2013-01-10T06:24:42.353 回答
1

这个词不是“特殊”,而是“默认”。

如果您选择不调用超类构造函数,A(int t)默认调用构造函数B(),因为 Java 无法为您决定哪个其他构造函数可以被视为默认构造函数。因此,如果B()不存在并且有调用它(如本例所示),则编译失败。

澄清一下,编译失败是因为你定义了 classA而不是因为 line B b = new B(5);,那行没问题。

于 2013-01-10T06:24:48.770 回答
1

B类中的无参数构造函数有什么特别之处,为什么代码必须存在才能工作?有什么特殊条件或规则?

--> 当你没有在你的类中提供任何构造函数时。编译器no-arg/default constructor在您的课程中添加。

如果您有带参数的构造函数,那么编译器将不会添加默认构造函数,如果需要,您必须添加。

于 2013-01-10T06:25:04.297 回答
1

除 Object 之外的所有类的构造函数必须以“this”调用开始,调用同一类的另一个构造函数,或者以“super”调用开始,调用超类构造函数。

如果在非 Object 构造函数的开头没有显式调用“this”或“super”,编译器实际上会插入一个简单的“super();”。

A 类构造函数实际上是:

    public A(int t)  {
        super();
        System.out.println("A's constructor is invoked");
    }

显然,必须有一个 B() 构造函数才能工作。

于 2013-01-10T06:29:51.490 回答
1

简而言之,子类构造函数的第一行是对super().
这是幕后发生的事情。

{
public A(int);
  Code:
   Stack=2, Locals=2, Args_size=2
   0:   aload_0
   1:   invokespecial   #1; //Method B."<init>":()V
   4:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   7:   ldc     #3; //String A's constructor is invoked
   9:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   12:  return
  LineNumberTable:
   line 11: 0
   line 13: 4
   line 14: 12

}

如您所见,第 1 行正在调用 B.init() ,这是默认构造函数 (no args) 。

这就是为什么您需要在 B 中使用无参数构造函数的原因。

于 2013-01-10T06:32:49.980 回答
1

如果 B 类中没有定义构造函数,那么就会有隐式的默认构造函数,否则需要显式定义无参数构造函数。

为什么我们需要无参数构造函数?

何时A通过构造函数实例化

public A(int t)  {

        System.out.println("A's constructor is invoked");
    }, 

有对 B() 的隐式 super() 调用,但是如果您没有定义无参数构造函数,则无法完成,这就是您收到错误消息的原因。

于 2013-01-10T06:22:32.230 回答