【问题标题】:Do I really need to define default constructor in java?我真的需要在java中定义默认构造函数吗?
【发布时间】:2011-04-08 03:41:29
【问题描述】:

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

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

【问题讨论】:

    标签: java constructor default-constructor


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • Link to the docs: "你不必为你的类提供任何构造函数,但是这样做时你必须小心。编译器会自动为任何没有参数的类提供一个无参数的默认构造函数构造函数。此默认构造函数将调用超类的无参数构造函数。在这种情况下,如果超类没有无参数构造函数,编译器会报错,因此您必须验证它是否存在。"
      • 而且默认情况下Object是所有类的超类,是否调用了Object的无参构造函数?
      • @Lucky 所有类确实隐式扩展Object,所以是的,Object() 被调用。
      【解决方案3】:

      这正是预期的行为。

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

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

      【讨论】:

        【解决方案4】:

        虽然上面的所有答案都是正确的,但对于新手来说,要记住它有点困难。我会尝试为新人重新回答这个问题。

        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 Tutorial

        【讨论】:

          【解决方案5】:

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

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

          但是,如果你在你的类中定义了参数化构造函数,这意味着你限制了对象拥有那个参数

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

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

          【讨论】:

            【解决方案6】:

            当您必须定义非参数构造函数时,还有一种奇怪的情况。 正如另一位所写,如果您不指定默认构造函数 - 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构造函数已经存在时无法自动生成。

            我知道这种情况非常罕见,但我觉得很有趣。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-12-13
              • 2015-04-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多