为什么我们在许多Java相关API中需要一个默认的无参数构造函数?像一般规则一样,所有java bean类或实体类(JPA等)或JAX-WS实现类都需要显式的无参数构造函数。
如果默认情况下Java提供了无参数构造函数,那么为什么这些标准中的大多数需要显式构造函数?
答案 0 :(得分:16)
如果没有定义其他构造函数,则Java仅提供默认的无参数构造函数 。因此,如果您有其他构造函数,则必须自己明确定义一个无参数构造函数。
这些框架使用反射API并查看方法名称以确定如何设置属性。构造函数的参数只能通过类型而不是名称来查找,因此框架无法可靠地将属性与构造函数args匹配。因此,它们需要一个无参数构造函数来创建对象,然后可以使用setter方法来初始化数据。
某些框架可能会支持@ConstructorProperties
作为替代方案。
答案 1 :(得分:11)
我认为需要public
nullary构造函数的框架是这样做的,因为它们使用反射来实例化类型,例如通过Class.newInstance()
。
至于为什么默认构造函数可能不适用于这种情况,这里是相关的JLS部分:
JLS 8.8.9 Default Constructor
如果
class
不包含构造函数声明,则会自动提供不带参数的默认构造函数:
- 如果
class
被声明为public
,则默认构造函数被隐式赋予访问修饰符public
;- 如果声明了类
protected
,则隐式赋予默认构造函数访问修饰符protected
;- 如果声明了类
private
,则隐式赋予默认构造函数访问修饰符private
;- 否则,默认构造函数具有默认访问权限隐含的默认访问权。
因此,在public
类中,默认构造函数具有正确的可见性,但是必须提供明确的public
类。
答案 2 :(得分:3)
如果没有应用其他构造函数,Java只提供无参数构造函数。在许多Java API(例如JPA,序列化和许多其他从外部表示构建对象)中,在设置对象的数据值之前需要对象的实例,因为值的应用方式的定义是通过对象的实例成员定义(例如readExternal(ObjectInput))。如果一个类只有一个带有一些参数的构造函数,那么除非定义了一个单独的无参数构造函数,否则库可能无法构造一个实例。
值得注意的是,这是特定库的实现者的设计选择,可以构建一个API / Framework,可以外部化并重新创建没有no-arg构造函数的对象(定义一个单独的工厂类是一种方法)。需要一个无参数构造函数的模式在Java Serialization(我认为)中首先出现,并且已被采用作为其他库(例如JPA)的事实上的标准方法。这种方法的缺点是它阻止了不可变对象的使用。
答案 3 :(得分:3)
需要构造函数来初始化任何非默认值,并且可以包含所需的副作用。
如果你有一个鼓励数据传输对象的最小构造函数的编程风格,这似乎是不必要的,但是库已经选择不为构造函数假设任何编程风格。
您可以编写一个不假定默认构造函数的库,但您必须对构造函数将执行和不执行的操作进行假设。即我已经编写了这样的库,但也能够强制允许构造函数执行,以便不直接调用它是安全的。
答案 4 :(得分:0)
两个原因: 1)如果参考数据类型的实例数据字段未初始化,则避免NullPointerException。提供显式构造函数将使您有机会初始化此类数据字段(如果它们在声明时尚未初始化) 2)对于想要使用无参数构造函数的用户;如果存在其他构造函数,则不会自动提供这些
答案 5 :(得分:0)