为什么我们在 Java 中需要一个默认的无参数构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3078389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do we need a default no argument constructor in Java?
提问by RRR_J
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.
为什么在许多 Java 相关的 API 中我们需要一个默认的无参数构造函数?作为一般规则,所有 java bean 类或实体类(JPA 等)或 JAX-WS 实现类都需要一个显式的无参数构造函数。
If by default Java provides a no argument constructor then why most of these standards require a explicit constructor?
如果默认情况下 Java 提供无参数构造函数,那么为什么这些标准中的大多数都需要显式构造函数?
回答by OrangeDog
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.
如果没有定义其他构造函数,Java 仅提供默认的无参数构造函数。因此,如果您有其他构造函数,则必须自己显式定义无参数构造函数。
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.
这些框架使用反射 API 并查看方法名称来确定如何设置属性。构造函数的参数只能通过类型而不是名称找到,因此框架无法可靠地将属性与构造函数参数匹配。因此,它们需要一个无参数构造函数来创建对象,然后可以使用 setter 方法来初始化数据。
Some frameworks may support @ConstructorPropertiesas an alternative.
一些框架可能支持@ConstructorProperties作为替代。
回答by polygenelubricants
I believe frameworks that require publicnullary constructors do so because they use reflection to instantiate types, e.g. through Class.newInstance().
我相信需要public空构造函数的框架这样做是因为它们使用反射来实例化类型,例如通过Class.newInstance().
As to why the defaultconstructor may not work for this case, here's the relevant JLS section:
至于为什么默认构造函数可能不适用于这种情况,这是相关的 JLS 部分:
JLS 8.8.9 Default Constructor
If a
classcontains no constructor declarations, then a default constructorthat takes no parameters is automatically provided:
- if the
classis declaredpublic, then the default constructor is implicitly given the access modifierpublic;- if the class is declared
protected, then the default constructor is implicitly given the access modifierprotected;- if the class is declared
private, then the default constructor is implicitly given the access modifierprivate;- otherwise, the default constructor has the default access implied by no access modifier.
JLS 8.8.9 默认构造函数
如果 a 不
class包含构造函数声明,则自动提供一个不带参数的默认构造函数:
- 如果
class声明了public,则默认构造函数被隐式赋予访问修饰符public;- 如果声明了类
protected,则默认构造函数被隐式赋予访问修饰符protected;- 如果声明了类
private,则默认构造函数被隐式赋予访问修饰符private;- 否则,默认构造函数具有无访问修饰符隐含的默认访问权限。
So in a publicclass, the default constructor would have the right visibility, but otherwise an explicitly publicone must be provided.
因此,在public类中,默认构造函数将具有正确的可见性,但否则public必须提供明确的可见性。
回答by Peter Lawrey
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.
您可以编写一个不假定默认构造函数的库,但您必须对构造函数会做什么和不会做什么做出假设。即我已经编写了这样的库,但也能够强制要求允许构造函数做什么,以便不直接调用它是安全的。
回答by Michael Barker
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.
如果没有应用其他构造函数,Java 仅提供无参数构造函数。在许多 Java API(例如 JPA、序列化和从外部表示构建对象的许多其他 API)中,在设置对象的数据值之前需要对象的实例,因为如何应用这些值的定义是通过对象的实例成员定义(例如 readExternal(ObjectInput))。如果一个类只有一个带一些参数的构造函数,那么库可能无法构造一个实例,除非定义了一个单独的无参数构造函数。
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.
值得注意的是,这是特定库的实现者的设计选择,可以构建一个 API/框架,可以外部化和重新创建没有无参数构造函数的对象(定义一个单独的工厂类是一种方法)。需要无参数构造函数的模式首先出现在 Java 序列化中(我认为),并已被采纳为其他库(例如 JPA)的事实上的标准方法。这种方法的弱点在于它阻止了不可变对象的使用。
回答by Nana
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
两个原因:1) 如果引用数据类型的实例数据字段未初始化,则避免 NullPointerException。提供显式构造函数将使您有机会初始化此类数据字段,如果它们在声明时尚未初始化 2) 对于想要使用无参数构造函数的用户;如果存在其他构造函数,则不会自动提供这些
回答by Axel Podehl
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'.
许多这些框架源自“ POJO”的早期思想,尤其是JavaBeans。按照惯例,最小的有用 Java 对象将有一个无参数构造函数,并且每个成员都可以通过 get/setProperty1 和 is/setProperty1 等方法访问布尔值。如果类遵循接口的约定,使用反射的工具和框架可以“开箱即用”。

