有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java默认构造函数真正做什么?

关于java中默认构造函数的真正作用,我有一些不理解的地方。在有关对象创建的官方教程中:

Creating Objects

All classes have at least one constructor. If a class does not explicitly declare any, the Java compiler automatically provides a no-argument constructor, called the default constructor. This default constructor calls the class parent's no-argument constructor, or the Object constructor if the class has no other parent. If the parent has no constructor (Object does have one), the compiler will reject the program.

在文档中,关于默认构造函数(§8.8.9

8.8.9. Default Constructor

If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.

因此,即使是类对象的默认构造函数也有一个空的主体。我知道默认构造函数不会将字段初始化为默认值,因为编译器会这样做:

Default Values

It's not always necessary to assign a value when a field is declared. Fields that are declared but not initialized will be set to a reasonable default by the compiler.

我不明白的是,如果我们没有声明构造函数,默认构造函数真正做什么


共 (4) 个答案

  1. # 1 楼答案

    没有构造函数,任何人都不能创建类的对象。现在,若程序员并没有添加任何带有类的构造函数,那个么java编译器会在编译之前添加带有该类的构造函数,这在java中称为默认构造函数

    但若程序员添加任何类型的构造函数(带参数或不带参数),那个么它将成为用户定义的构造函数,并且不会通过java编译器添加任何构造函数

    现在的问题是构造函数做什么

    1. 为新对象分配内存
    2. 如果用户定义了任何其他操作,如初始化变量,则此操作已完成
  2. # 2 楼答案

    在Java中,如果不声明任何构造函数,编译器将创建一个默认构造函数,并调用super()方法,即父构造函数。在这个过程中,inits实例变量没有默认的构造函数

  3. # 3 楼答案

    what does the default constructor really do?

    它调用super()。按照你们所有的报价。除此之外什么也不做JLS #8.8.9

    If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.

    也就是说,它不做其他事情。对于那些相信它初始化实例变量的人,请参见JLS #12.5,其中断言了相反的结果

  4. # 4 楼答案

    What I don't understand is, if we didn't declare a constructor, what does the default constructor really do ?

    默认情况下,如果未声明构造函数,则类具有不带参数的默认构造函数
    我认为这就是为什么默认情况下所有构造函数调用super()。它可能遵循配置原则之上的约定

    无论您声明一个public构造函数还是根本不声明构造函数,构造函数的第一条指令都是super()
    这就是为什么如果在类MyClass中定义一个带args的构造函数MyClass(String s),而不保留一个没有参数的构造函数,MyClass子类的构造函数无法编译,而在它们的第一条指令中它并不精确,在示例中,对现有父构造函数的调用将是super(String ...)

    这里有一个例子:

    public class MyClassWithNoArg{
      public MyClassWithNoArg(){
      }
    }
    

    MyClassWithNoArg构造函数在第一条指令中调用super(),即使它没有在源代码中指定

    就好像是这样写的:

    public class MyClassWithNoArg{
      public MyClassWithNoArg(){
         super();
      }
    }
    

    现在想象另一个类MyClassWithArg

    public class MyClassWithArg{
      public MyClassWithNoArg(String s){
      }
    }
    

    MySubclass一个MyClassWithArg的子类

    public class MySubclass extends MyClassWithArg{
      public MySubclass (String s){
      }
    
      public MySubclass (){
      }
    }
    

    在这两种情况下,它都不会编译,因为如前所述,默认情况下,所有构造函数都调用其父级的默认构造函数(super()),但在这里,父级MyClassWithArg没有不带参数的构造函数。所以,它不编译

    所以要解决这个问题,必须调用存在的超级构造函数

    public class MySubclass extends MyClassWithArg{
      public MySubclass (String s){
         super(s);
      }
    
      public MySubclass (){
        super("");
      }
    }
    

    现在,编译就可以了