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

发布于 2024-09-06 00:07:35 字数 157 浏览 10 评论 0原文

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

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

Why do we need a default no argument constructor in many Java related APIs? Like as a general rule all java bean classes or entity classes (JPA etc) or JAX-WS implementation classes require a explicit no argument constructor.

If by default Java provides a no argument constructor then why most of these standards require a explicit constructor?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

浅唱々樱花落 2024-09-13 00:07:36

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

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

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

Java only provides a default no-argument constructor if no other constructors are defined. Thus, if you have other constructors you must explicitly define a no-arg constructor yourself.

These frameworks use the reflection API and look at method names to determine how to set properties. The arguments of a constructor can only be found by type, not by name, so there is no way for the framework to reliably match properties to constructor args. Therefore, they require a no-arg constructor to create the object, then can use the setter methods to initialise the data.

Some frameworks may support @ConstructorProperties as an alternative.

泼猴你往哪里跑 2024-09-13 00:07:36

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

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

JLS 8.8.9 默认构造函数

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

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

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

I believe frameworks that require public nullary constructors do so because they use reflection to instantiate types, e.g. through Class.newInstance().

As to why the default constructor may not work for this case, here's the relevant JLS section:

JLS 8.8.9 Default Constructor

If a class contains no constructor declarations, then a default constructor that takes no parameters is automatically provided:

  • if the class is declared public, then the default constructor is implicitly given the access modifier public;
  • if the class is declared protected, then the default constructor is implicitly given the access modifier protected;
  • if the class is declared private, then the default constructor is implicitly given the access modifier private;
  • otherwise, the default constructor has the default access implied by no access modifier.

So in a public class, the default constructor would have the right visibility, but otherwise an explicitly public one must be provided.

简单气质女生网名 2024-09-13 00:07:36

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

如果您的编程风格鼓励数据传输对象使用最小构造函数,那么这似乎是不必要的,但库选择不为构造函数假设任何编程风格。

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

A constructor is needed to initialise any non-default values and can contain side effects which are needed.

If you have a programing style which encourages a minimal constructor for data transfer objects this would seem unneccasary, but the libraries have chosen not to assume any programming style for the constructors.

You can write a library which doesn't assume a default constructor, but you have to make assumptions about what the constructor would do and wouldn't do. i.e. I have written such libraries but was able to also mandate what a constructor was allowed to do so that not calling it directly was safe.

人生百味 2024-09-13 00:07:36

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

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

Java only supplies a no-arg constructor if no other constructor is applied. In a number of Java APIs (e.g. JPA, Serialisation and many others that build objects from an external representation) an instance of the object is required before the data values of the object can be set, as the definition of how the values are applied are defined through instance members of the object (e.g. readExternal(ObjectInput)). If a class only has a constructor that takes some arguments then it may not be possible for the library to construct an instance unless a separate no-arg constructor is defined.

It is worth noting that this is a design choice by the implementer of the particular library, it is possible to build an API/Framework that can externalise and recreate objects that don't have a no-arg constructor (defining a separate factory class is one approach). The pattern of requiring a no-arg constructor turned up first in Java Serialisation (I think) and has been adopted as the de-facto standard approach on other libraries (e.g. JPA). The weakness of this approach is that it prevents the use of immutable objects.

怎会甘心 2024-09-13 00:07:36

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

Two reasons:
1) to avoid NullPointerException if an instance data field of a reference data type is uninitialized. Providing an explicit constructor would give you the chance to initialize such data fields, if they have not been initialized when declared
2) for users who would like to use no-arg constructors; these are not automatically provided if other constructors exist

司马昭之心 2024-09-13 00:07:36

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

Many of these frameworks derive from the earlier ideas of "POJO" and especially JavaBeans. The smallest useful Java Object would, by convention, have a no-arg constructor and every member accessible through methods like get/setProperty1 and is/setProperty1 for booleans. If Classes follow that convention of the interface, tools and frameworks using reflection can work 'out of the box'.

烈酒灼喉 2024-09-13 00:07:36

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

Default No-Argument constructor provides default values to the object like 0 or null, hence it is mandatory in java coding.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文