我们可以在Java中使用构造函数的返回类型吗?

use*_*814 10 java constructor

以下代码给出了编译错误:

class parent {
  parent(int a){}
}

class child extends parent{}
Run Code Online (Sandbox Code Playgroud)

错误:

Main.java:6: cannot find symbol
symbol  : constructor parent()
location: class parent
class child extends parent{}
^
1 error
Run Code Online (Sandbox Code Playgroud)

我试图做不同的事情,发现向父构造函数添加一个返回类型摆脱了错误!

class parent {
  int parent(int a){}
}

class child extends parent{}
Run Code Online (Sandbox Code Playgroud)

我已经读过构造函数不应该有返回类型,这显然不是一直都是正确的.所以我的问题是我们什么时候应该有构造函数的返回类型?

cod*_*ict 29

case 1中,子类没有任何构造函数,因此编译器会为您添加一个默认构造函数,并且还会添加对超类构造函数的调用.所以你的孩子班有效地看起来像:

class child extends parent {
 child() {
  super();
 }
}
Run Code Online (Sandbox Code Playgroud)

该调用super()在基类中查找零参数构造函数,因为没有这样的构造函数可以获得错误.

案例2父父类没有任何构造函数

int parent(int x) {}不是因为它有一个返回类型的构造函数.它只是一个具有类名的方法.子类也没有任何构造函数.因此,编译器为child和parent添加了默认构造函数,并且还添加了对超类构造函数的调用:

class parent {
 parent() {
  super(); // calls Object class ctor.
 }
  int parent(int x) {} // not a ctor.
}

class child extends parent {
 child() {
  super();
 }
}
Run Code Online (Sandbox Code Playgroud)


pol*_*nts 18

在没有返回类型的构造函数上

构造函数不能具有返回类型.根据定义,如果方法具有返回类型,则它不是构造函数.

JLS 8.8构造函数声明

构造函数用于创建作为类实例的对象.[名称必须与类名匹配,但是]在所有其他方面,构造函数声明看起来就像没有结果类型的方法声明.


在默认构造函数上

以下代码段确实给出了编译错误:

class Parent {
   Parent(int a){}
}

class Child extends Parent{

   // DOES NOT COMPILE!!
   // Implicit super constructor parent() is undefined for default constructor.
   // Must define an explicit constructor

}
Run Code Online (Sandbox Code Playgroud)

原因不是因为构造函数中的返回类型,而是因为您没有为其提供任何构造函数Child,所以编译器会自动为您创建默认构造函数.然而,这个默认的构造函数试图调用父类的默认构造函数Parent,它确实具有默认构造函数.THAT'S FO的编译错误的源.

这是默认构造函数的规范:

JLS 8.8.9默认构造函数

如果类不包含构造函数声明,则会自动提供不带参数的默认构造函数:

  • 如果声明的类是原始类Object,则默认构造函数具有空体.
  • 否则,默认构造函数不带参数,只调用不带参数的超类构造函数.

以下是一个简单的修复:

class Parent {
   Parent(int a){}
}

class Child extends Parent{

   // compiles fine!
   Child() {
      super(42);
   }

}
Run Code Online (Sandbox Code Playgroud)

在与构造函数同名的方法上

下面的代码片段DOES编译:

// COMPILES FINE!!

class Parent  {

   // method has same name as class, but not a constructor
   int Parent(int a) {
      System.out.println("Yipppee!!!");
      return 42;
   }

   // no explicit constructor, so default constructor is provided
}

class Child extends Parent {

   // no explicit constructor, so default constructor is provided

}
Run Code Online (Sandbox Code Playgroud)

实际上在上面的代码片段中没有明确的构造函数.你拥有的是一个与类同名的常规方法.这是允许的,但不鼓励:

JLS 8.4方法声明

A class可以声明一个方法,该方法与该类class的字段,成员class或成员具有相同的名称interface,但不鼓励这样做.

你会发现,如果你创建一个new Parent()或一个new Child(),"Yipppee!!!"不会打印到标准输出.该方法在创建时不会被调用,因为它不是构造函数.


Boz*_*zho 5

  • 当您扩展一个没有默认构造函数的类时,您必须提供一个调用该超构造函数的构造函数 - 这就是编译错误的原因,即:

默认构造函数的隐式超级构造函数 parent() 未定义。必须定义一个显式构造函数

  • 当您添加返回类型时,这不再是构造函数,而是方法,并且上述内容不适用

将来首先阅读错误消息,并尝试推理(或找到)它的含义。