这对你来说可能听起来很愚蠢,
但为什么我需要在@Entity
s中定义一个空构造函数?
我看到的每个教程都说:每个实体都需要一个空的构造函数。
但是Java总是给你一个默认的不可见的空构造函数(如果你不重新定义它)。
感谢。
我认为存在语义问题。 我对“需要”所理解的是写作。
含义:总是在你的实体中写一个空的构造函数。
示例:
@Entity
public class MyEntity implements Serializable {
@Id
private String str;
public MyEntity(){}
//here getter and setter
}
但是当你不重新定义它时,Java总会给你这个空的构造函数(用参数写另一个)。
在这种情况下,编写这个空构造函数似乎没用。
答案 0 :(得分:36)
需要空构造函数来通过持久性框架的反射来创建新实例。如果您没有为该类提供任何其他带有参数的构造函数,则不需要提供空构造函数,因为每个默认值都会得到一个。
您还可以使用@PersistenceConstructor注释,如下所示
@PersistenceConstructor
public Movie(Long id) {
this.id = id;
}
如果您的项目中存在Spring Data,则初始化您的实体。因此,您也可以避免使用空构造函数。
答案 1 :(得分:24)
但java总是给你一个默认的不可见的空构造函数(如果你 不要重新定义一个。)
只有在类中未提供任何构造函数时,此语句才为真。如果在类中提供了参数构造函数,那么jvm将不会添加无参构造函数。
答案 2 :(得分:5)
除非为实体提供另一个构造函数,否则不必显式定义默认构造函数。如果您提供另一个构造函数,除了具有默认构造函数签名的构造函数之外,将不会创建默认构造函数。
由于JPA实现依赖于默认构造函数的存在,因此必须包含将被省略的默认构造函数。
答案 3 :(得分:3)
当您指定“JPA”标记时,我假设您的问题仅适用于JPA,而不适用于空构造函数。
Persitence框架经常使用反射,更具体地说是Class<T>.newInstance()
来实例化你的对象,然后通过内省调用getters / setter来设置字段。
这就是为什么你需要一个空的构造函数和getter / setter。
请参阅this StackOverflow question about empty constructors in Hibernate.
答案 4 :(得分:1)
实际上你不需要写它。你默认拥有它。有时您可以创建private
构造函数以防止用户使用默认
public class MyClass{
private MyClass(){}
}
对于singelton模式,例如,您可以阻止使用默认构造函数。
有时候,当你使用Gson
插件将String Json数据转换为Object时,它需要编写默认构造函数,否则它不起作用
答案 5 :(得分:0)
如果您的类有参数构造函数,Java并不总是为您提供默认的不可见空构造函数,您必须自己定义空构造函数。
答案 6 :(得分:0)
所有答案都很好。
但是让我们谈谈代码。遵循以下代码片段将使您更加清晰。
PersonWithImplicitConstructor.java
public class PersonWithImplicitConstructor {
private int id;
private String name;
}
首先,我们必须编译.java
文件
javac PersonWithImplicitConstructor.java
然后将生成类文件。
在该类文件的顶部运行javap
将为您提供以下信息。
javap PersonWithImplicitConstructor.class
Compiled from "PersonWithImplicitConstructor.java"
public class PersonWithImplicitConstructor {
public PersonWithImplicitConstructor();
}
注意::如果您想了解更多信息,可以在-p
上使用javap
标志。
下一个Java文件将仅具有参数化的构造函数。
PersonWithExplicitConstructor.java
public class PersonWithExplicitConstructor {
private int id;
private String name;
public PersonWithExplicitConstructor(int id, String name) {
this.id = id;
this.name = name;
}
}
javac PersonWithExplicitConstructor.java
javap PersonWithExplicitConstructor.class
Compiled from "PersonWithExplicitConstructor.java"
public class PersonWithExplicitConstructor {
public PersonWithExplicitConstructor(int, java.lang.String);
}
PersonWithBothConstructors.java
public class PersonWithBothConstructors {
private int id;
private String name;
public PersonWithBothConstructors() {
}
public PersonWithBothConstructors(int id, String name) {
this.id = id;
this.name = name;
}
}
javac PersonWithBothConstructors.java
javap PersonWithBothConstructors.class
Compiled from "PersonWithBothConstructors.java"
public class PersonWithBothConstructors {
public PersonWithBothConstructors();
public PersonWithBothConstructors(int, java.lang.String);
}
答案 7 :(得分:-1)
从JPA标记中,我认为您正在使用Java bean。每个bean都需要具有以下属性:
所有主要实例变量的getter和setter。
空构造函数。
其所有实例变量最好为private
。
因此声明:“每个实体都需要一个空构造函数”。