36

它在未定义构造函数时工作正常,但如果我定义参数化构造函数而不是默认构造函数并且在创建对象时不传递任何值,则会出错。我认为构造函数是预定义的。

如果我定义了参数化构造函数,为什么还需要定义默认构造函数?默认构造函数不是预定义的吗?

4

6 回答 6

64

当您自己未定义任何构造函数时,才会自动创建默认(无参数)构造函数。

如果您需要两个构造函数,一个带参数,一个不带参数,则需要手动定义两者。

于 2010-09-04T06:10:04.410 回答
19

虽然以上所有答案都是正确的,但对于新手来说,将其包装在脑海中有点困难。我将尝试为新人重新回答这个问题。

Ayush 面临的问题是试图Object通过无参数构造函数实例化一个类。但是,此类具有一个或多个参数化构造函数,这会导致编译时错误。

例如,让我们创建一个Student具有单个参数化构造函数的类,并尝试通过无参数构造函数实例化它。

public class Student {

    private String name;
    private int rollNo;

    public Student(String name, int rollNo) {
        this.name = name;
        this.rollNo = rollNo;
    }

    public static void main(String[] args) {
        // The line below will cause a compile error.
        Student s = new Student();
        // Error will be "The constuctor Student() is undefined"
    }
}

哇!但是当我们一起删除public Student(String name, int rollNo) 构造函数时,错误消失了,代码编译了。

这种看似异常的背后原因在于,当我们自己没有为该类定义任何构造函数时,Java 只为我们提供了默认(无参数)构造函数。

例如,以下类提供了一个默认构造函数:

public class Student {
    private String name;
    private int rollNo;
}

变成:

public class Student {

    private String name;
    private int rollNo;

    //Default constructor added by Java.
    public Student() {
        super();
    }
}

换句话说,当我们定义任何参数化构造函数时,如果我们想通过无参数构造函数实例化该类的对象,我们还必须定义一个无参数构造函数。

同样在继承的情况下,没有构造函数的子类;提供了一个默认构造函数。上面由 Java 提供的这个默认构造函数调用超类的无参数构造函数。如果找不到,则会抛出错误。

所以是的,定义无参数/默认构造函数总是一个不错的选择。

参考:Oracle Java 教程

于 2014-04-11T03:10:21.980 回答
11

如果您不编写无参数构造函数,则会自动为您插入一个。这意味着,如果您编写带有一些参数的构造函数,它将是您拥有的唯一构造函数,因此您必须为这些参数传递一些值才能创建它的实例。

于 2010-09-04T06:09:34.147 回答
2

这正是预期的行为。

Java 会自动为没有任何构造函数的类生成默认值(无参数构造函数)。

如果您定义另一个构造函数(带参数),则不会生成默认构造函数。如果你仍然想要一个,你需要自己定义它。

于 2010-09-04T06:11:21.110 回答
1

每当您的类被编译时,如果编译器在类中没有找到任何有效的构造函数(默认,参数化),那么它将用自动生成的默认构造函数代替您的类。

你一定注意到了,你可以在没有在你的类中定义任何默认构造函数的情况下创建对象,由此产生了自动生成默认构造函数的概念。就像每当创建对象时,都会调用默认构造函数。

但是,如果您在类中定义了参数化构造函数,这意味着您将对象限制为具有该参数

示例:每个员工都必须有一个 id。

所以,此时Compiler不会在其中插入任何默认构造函数,因为类中有有效的构造函数。如果您也需要默认构造函数,则必须自己定义。

于 2015-06-23T11:02:54.110 回答
1

当您必须定义非参数构造函数时,还有一种奇怪的情况。正如另一位所写,如果您不指定默认构造函数 - Java 会为您完成。很高兴了解“Java 生成的默认值”构造函数的样子。实际上它调用了超类的构造函数,这很好。现在让我们想象一个案例。您正在创建 Vehicle 类:

public class Vehicle {
private String name;
private String engine;

public Vehicle(String name, String engine) {
    this.name = name;
    this.engine = engine;
}

public String makeNoise(){
    return "Noiseee";
} 
}

正如我们所见,Vehicle 类只有一个定义的 2 参数构造函数。现在让我们创建继承自 Vehicle 类的 Car 类:

public class Car extends Vehicle {

@Override
public String makeNoise() {
    return "Wrrrrrrr....";
}  }

也许它看起来很奇怪,但它不能编译的唯一原因是 Java 无法为调用超级 Vehicle 类的 Car 类创建默认构造函数。车辆类没有无参数构造函数,并且当 2 arg 构造函数已经存在时无法自动生成。

我知道这是非常罕见的情况,但我发现它很有趣。

于 2019-10-01T21:24:16.227 回答