java中默认构造函数的实际用途是什么?

What is the actual use of the default constructor in java?

我在很多资料和书籍中都读到构造函数用于在创建对象时初始化字段。我还读到 JVM 提供了一个默认构造函数(如果我没有提到的话)。如果不需要像我下​​面提到的那样初始化字段,构造函数的目的是什么?

I also understand that a constructor without parameter is required as it is necessary during object creation when an argument is not passed (when programmer-defined constructors with parameters exists).

JVM有必要提供一个实际上不需要的构造函数吗?

 public class test {
        int a;
        public test() { 
       //this constructor is useless

    }
public static void main(String[] args)
{ 
  test ob= new test();
  System.out.println(ob.a); 
//this prints 0 which means a constructor is not required in intialising `a`
}
}

如果程序员定义了像 test() 这样的构造函数是有意义的,因为可能有其他构造函数接受参数。 但是为什么在程序员没有声明构造函数的情况下JVM有必要提供一个呢?

我已经测试证明初始化字段不需要构造函数。

默认构造函数是什么样子的?

构造函数(默认和自定义构造函数)不仅用于初始化对象的字段,还用于初始化对象本身,即使它根本没有字段。调用构造函数,JVM 为这个对象分配内存并创建它的引用。

JVM 在您未提供默认构造函数的情况下添加默认构造函数的原因在于继承。例如,假设您有 3 类 (A, B & C),其中 B 扩展 A,C 扩展 B。现在当您实例化 C 时,它将调用 C 的构造函数以及 B 和 A 的构造函数。如果其中一个或多个 类 中缺少构造函数,则实例化将失败。所以让编译器自动添加默认构造函数可以避免这样的错误。您可能不需要在构造函数中实际执行任何工作,但 JVM 需要实例化对象。

在此处创建对象 new test() 时, 这里括号表示对象 test.After 创建对象的默认构造函数,如果你没有给任何构造函数,则默认构造函数由 jvm.so 在构造你的对象后第一次调用转到你的默认构造函数。

问题是,虽然您知道默认构造函数在此示例中不做任何事情,但将来构造函数可能会做一些事情,即使您没有意识到它也是如此,并且您可能无法重新编译在任何地方都可以可靠地使用代码。因此,最安全、最简单的做法是始终调用将来可能会更改的构造函数,如果构造函数实际上什么都不做,则让 JIT 优化它。


无论您提供与否,字节码总是调用一个构造函数。当您编译使用默认构造函数的代码时,它不能假设构造函数没有做任何有用的事情,因为您可以稍后向它添加一些东西来做一些有用的事情。例如

说你变了

public class Test {
    int a;

    // public Test() { //this constructor does nothing
}

public class Test {
    int a;
    final List<String> strings = new ArrayList<>();

    // public Test() { //this constructor does something now.
}

public class ServerTest {
    final List<String> strings = new ArrayList<>();
}

public class Test extends SuperTest {
   int a;
   // the default constructor has to call super();
}

构造函数现在初始化了 strings 字段。您可以更改此 class 而无需在使用它的所有地方重新编译并说,嘿,我的构造函数现在做了一些有用的事情,您现在应该调用它。

默认构造函数是一个无参数构造函数,当您没有定义任何构造函数时,编译器会自动调用它。无论如何,您定义的构造函数也可以称为默认构造函数。 它基本上使用 super() 方法调用超类的构造函数。 所以自动调用的默认构造函数类似于:

public 类名(){

超级();

}

  1. 在缺席时插入默认构造函数的是编译器,而不是 JVM。
  2. 需要默认构造函数,因为需要从构造函数调用基础 class 的构造函数。
  3. 默认构造函数如下所示:

    public Test() {
        super();
    }
    
如果没有为 class.

定义其他构造函数,

Java 的编译器将创建一个默认构造函数

但是为什么呢?

编译器的工作是将 Subclass 的构造函数链接到 Super Class(最终是 Object class)。为您的 class 提供默认构造函数不是编译器的工作,因此 Java 正在为您做这件事。

为了进行链接,它首先检查 class 中是否有任何构造函数,如果有,它将向该构造函数添加 super()。

如果 class 中没有定义构造函数以便编译器进行正确的链接,Java 添加一个默认构造函数并调用 super() 到其中。

为什么?

因为每一个class都是一个对象class的子class(直接或间接),它会继承一个对象class,所以说对象 class 必须完全初始化。这是由默认构造函数完成的。