繁体   English   中英

为什么我们在 Java 中需要一个默认的无参数构造函数?

[英]Why do we need a default no argument constructor in Java?

为什么我们需要在许多 Java 相关 API 中使用默认的无参数构造函数? 作为一般规则,所有 java bean 类或实体类(JPA 等)或 JAX-WS 实现类都需要显式无参数构造函数。

如果默认情况下 Java 提供无参数构造函数,那么为什么大多数这些标准都需要显式构造函数?

如果没有定义其他构造函数, Java仅提供默认的无参数构造函数 因此,如果您有其他构造函数,则必须自己明确定义一个无参数构造函数。

这些框架使用反射API并查看方法名称以确定如何设置属性。 构造函数的参数只能通过类型而不是名称来查找,因此框架无法可靠地将属性与构造函数args匹配。 因此,它们需要一个无参数构造函数来创建对象,然后可以使用setter方法来初始化数据。

一些框架可能支持@ConstructorProperties作为替代方案。

我相信需要public nullary构造函数的框架是这样做的,因为它们使用反射来实例化类型,例如通过Class.newInstance()

至于为什么默认构造函数可能不适用于这种情况,这里是相关的JLS部分:

JLS 8.8.9默认构造函数

如果class包含构造函数声明,则会自动提供不带参数的默认构造函数

  • 如果class被声明为public ,则默认构造函数被隐式赋予访问修饰符public ;
  • 如果该类被声明为protected ,则默认构造函数被隐式赋予访问修饰符protected ;
  • 如果该类被声明为private ,则默认构造函数被隐式赋予访问修饰符private ;
  • 否则,默认构造函数具有无访问修饰符隐含的默认访问权限。

因此,在public类中,默认构造函数具有正确的可见性,但是否则必须提供明确的public构造函数。

如果没有应用其他构造函数,Java仅提供无参数构造函数。 在许多Java API(例如JPA,序列化和许多其他从外部表示构建对象)中,在设置对象的数据值之前需要对象的实例,因为值的应用方式的定义是通过对象的实例成员定义(例如readExternal(ObjectInput))。 如果一个类只有一个带有一些参数的构造函数,那么除非定义了一个单独的无参数构造函数,否则库可能无法构造一个实例。

值得注意的是,这是特定库的实现者的设计选择,可以构建一个API / Framework,可以外化和重新创建没有no-arg构造函数的对象(定义一个单独的工厂类是一种方法)。 需要一个无参数构造函数的模式在Java Serialization(我认为)中首先出现,并且已被采用作为其他库(例如JPA)的事实上的标准方法。 这种方法的缺点是它阻止了不可变对象的使用。

需要构造函数来初始化任何非默认值,并且可以包含所需的副作用。

如果你有一个编程风格,鼓励数据传输对象的最小构造函数,这似乎是不必要的,但库已选择不为构造函数假设任何编程风格。

您可以编写一个不假定默认构造函数的库,但您必须假设构造函数将执行和不执行的操作。 即我已经编写了这样的库,但也能够强制允许构造函数做什么,以便不直接调用它是安全的。

有两个原因:1)如果参考数据类型的实例数据字段未初始化,则避免NullPointerException。 提供一个显式构造函数可以让你有机会初始化这些数据字段,如果它们在声明2)时尚未初始化,对于想要使用no-arg构造函数的用户; 如果存在其他构造函数,则不会自动提供这些

其中许多框架源自早期的“ POJO ”思想,尤其是JavaBeans 按照惯例,最小的有用Java对象具有无参数构造函数,并且每个成员都可以通过get / setProperty1和/ setProperty1等方法访问布尔值。 如果Classes遵循接口的约定,那么使用反射的工具和框架可以“开箱即用”。

默认无参数构造函数为 object 提供默认值,如 0 或 null,因此在 java 编码中是强制性的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM