【问题标题】:Difference between a no-arg constructor and a default constructor in JavaJava中无参数构造函数和默认构造函数之间的区别
【发布时间】:2015-02-23 14:11:00
【问题描述】:

其实我不明白无参数构造函数和默认构造函数有什么区别。

import javax.swing.*;

public class Test extends JFrame {
   public Test() {
     super();
     this.setSize(200,200);
     this.setVisible(true);
   }
   public static void main(Sting[] arg) {
       Test cFrame = new Test();
   }
}

在创建名为 cFrame 的 Test 对象时,是否会调用此类的默认构造函数?

【问题讨论】:

  • 不,它不会调用默认构造函数,现在没有默认构造函数
  • 我的两分钱:默认构造函数只能调用基类的无参数构造函数。

标签: java constructor default-constructor


【解决方案1】:

default 构造函数是 Java 编译器代表您插入的无参数构造函数;它包含对super();(不是supper())的default 调用,这是默认行为。如果您实现任何构造函数,那么您将不再收到默认构造函数。

JLS-8.8.9. Default Constructor 说(部分),

如果一个类不包含构造函数声明,则隐式声明一个没有形式参数且没有 throws 子句的默认构造函数。

如果声明的类是原始类 Object,则默认构造函数的主体为空。否则,默认构造函数只会调用不带参数的超类构造函数。

【讨论】:

  • 我是任何给supper()的电话的忠实粉丝
  • @JonathanLandrum Java 中真的有一个方法作为 supper() 吗?
  • "如果您实现任何构造函数,那么您将不再收到默认构造函数。" - 那么添加我自己的构造函数后,开发者应该再次键入无参数构造函数还是Java隐式添加它?
  • @user3705478 很抱歉造成误解;那条评论是开玩笑的。英文单词“supper”是一个古老的用餐术语,尤其是在晚上和陪伴的时候。同样,“叫晚餐”是通知饭菜准备好了。
【解决方案2】:

default constructor 是一个构造函数,如果没有可用的显式构造函数,Java 编译器会将其添加到您的代码中。 默认构造函数调用不带参数的超类构造函数。

如果你添加了自己的构造函数(无论是无参数还是有参数)编译器在这种情况下不会添加默认构造函数。

【讨论】:

    【解决方案3】:

    什么是默认构造函数?

    如果你没有定义构造函数,它是编译器添加的构造函数。

    如果你的类已经有构造函数,那么编译器不会添加默认构造函数。

    所以在你的情况下你有构造函数,

    public Test(){
         super();
         this.setSize(200,200);
         this.setVisible(true);
       }
    

    因此,现在 JVM 不会调用默认构造函数。

    【讨论】:

      【解决方案4】:

      答案是否定的。引用变量 cFrame 将调用非参数构造函数 Test(),而不是默认构造函数。而Test()构造函数会进一步查找并调用JFrame类(Parent)的非参数构造函数等等 每个类必须至少有一个构造函数。如果没有显式声明,java 编译器会提供一个非参数化的构造函数,即默认构造函数。此默认构造函数调用其父类的非参数化构造函数,它将类变量初始化为其默认值。

      例如:

      Class Base {}
      
      Class Derived extends Base {} // Default constructor of class "Derived" will automatically calls non-arg constructor of class "Base" and intialzes value to the variables
      

      虽然非参数构造函数仅由程序员定义。它还可以初始化变量。这里还要补充一点,如果在派生类中找不到 super(),java 编译器会自动添加 super() 调用。

      例如:

      Class Base {
      
      int y;
          public Base() {
          }
          public int getY() {
          return y;
          }
      
      }
      
      public class Derived extends Base {
       private int x;
      
       public Derived() { //super() will be automatically used
       }
      
       public int getX() {
       return x;
       }
      
       public void setX(int x) {
       this.x = x;
       }
      }
      
      Derived d = new Derived();
       System.out.println("Base x value => " + d.getX());
      
      System.out.println("Base y value => " + d.getY());
      
      Result:
      
      Base x value => 0 // Default value to its primitive datatype(In this case: int)
      
      Base y value => 0
      

      【讨论】:

        【解决方案5】:

        默认构造函数就像它的名字一样,如果我们不显式创建构造函数,那么java编译器将创建一个默认构造函数。作为开发人员,如果我们创建自己的构造函数,其参数为 0,那么它将是无参数构造函数。

        【讨论】:

          【解决方案6】:

          您的问题的答案是否定的。如果您在类中编写任何类型的构造函数,Java 将不会提供默认构造函数。

          它们之间的一个区别是默认构造函数的主体总是空的,而我们可以在无参数构造函数中插入我们自己的代码。

          【讨论】:

            【解决方案7】:

            Java 中“默认构造函数”和“无参数构造函数”的概念很容易混淆。原因是默认构造函数是一种特殊的无参数构造函数。但是,并非所有无参数构造函数都是默认构造函数。

            如果类的源代码中出现any构造函数,即使是空的无参构造函数,也不会生成默认构造函数,也不存在。因为Test声明了构造函数,它没有默认构造函数,所以Test cFrame = new Test();没有调用默认构造函数。

            这两个类在行为方面是相同的(都有一个不做任何事情的无参数构造函数),但是一个有一个默认构造函数,另一个没有。

            class NoDefaultConstructor {
                NoDefaultConstructor() {
                    // This is a no-argument constructor with an empty body, but is not a default constructor.
                }
            }
            
            class HasDefaultConstructor {
                // This class has no declared constructors, so the compiler inserts a default constructor.
            }
            

            在每种情况下,您都可以使用new NoDefaultConstructor() 或new HasDefaultConstructor() 创建一个实例,因为这两个类都有无参数构造函数,但只有HasDefaultConstructor 的无参数构造函数是默认构造函数。

            样式说明:如果构造函数没有通过调用super(...) 或this(...) 显式链接到另一个构造函数,则对super() 的调用会自动插入到构造函数的开头。您从不需要在 Java 构造函数中编写 super()。这样做会增加视觉噪音,而且是不必要的。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-02-08
              • 1970-01-01
              • 2016-06-05
              • 2015-02-24
              • 1970-01-01
              • 2016-03-24
              • 1970-01-01
              相关资源
              最近更新 更多