48

这对你来说可能听起来很愚蠢,但是为什么我需要在我@Entity的 s 中定义一个空的构造函数呢?

我看到的每个教程都说:每个实体都需要一个空的构造函数。

但是 Java 总是给你一个默认的不可见的空构造函数(如果你不重新定义一个)。

让我澄清一下。我对“需要”的理解是write

含义:始终在您的实体中编写一个空的构造函数。

例子:

@Entity
public class MyEntity implements Serializable {

   @Id
   private String str;

   public MyEntity(){}

   //here getter and setter
}

但是当你不重新定义它时,Java总是给你这个空的构造函数(写另一个带参数的构造函数)。

在这种情况下,编写这个空构造函数似乎没用。

4

8 回答 8

55

需要一个空的构造函数来通过持久性框架的反射创建一个新实例。如果您没有为该类提供任何带有参数的其他构造函数,则不需要提供空构造函数,因为每个默认值都会得到一个。

您还可以使用如下所示的 @PersistenceConstructor 注释

@PersistenceConstructor
public Movie(Long id) {
    this.id = id;
}

如果项目中存在 Spring Data,则初始化您的实体。因此,您也可以避免使用空构造函数。

于 2013-08-07T09:14:52.017 回答
34

但是java总是给你一个默认的不可见的空构造函数(如果你不重新定义一个)。

仅当您未在类中提供任何构造函数时,此语句才成立。如果您的类中提供了参数构造函数,则 jvm 将不会添加无参数构造函数。

于 2013-08-07T09:08:00.067 回答
7

除非您为实体提供另一个构造函数,否则不需要显式定义默认构造函数。如果您提供另一个构造函数,除了具有默认构造函数签名的构造函数之外,将不会创建默认构造函数。

由于 JPA 实现依赖于默认构造函数的存在,因此有必要包含将被省略的默认构造函数。

于 2013-08-07T09:07:57.900 回答
5

当您指定“JPA”标签时,我假设您的问题仅适用于 JPA,而不适用于一般的空构造函数。

持久性框架通常使用反射,更具体地说Class<T>.newInstance()是实例化您的对象,然后通过自省调用 getter/setter 来设置字段。

这就是为什么你需要一个空的构造函数和 getter/setter。

请参阅有关 Hibernate 中的空构造函数的 StackOverflow 问题。

于 2013-08-07T09:15:36.273 回答
3

其实你不需要写。您默认拥有它。有时您可以创建private构造函数以防止用户使用默认值

public class MyClass{

private MyClass(){} 

} 

例如,对于单例模式,您可以使用默认构造函数进行阻塞。

有时,当你使用Gson插件将String Json数据转换为Object时,它要求编写默认构造函数,否则不起作用

于 2013-08-07T09:08:42.090 回答
1

所有的答案都很好。

但是让我们谈谈代码。以下代码片段将使您更加清晰。

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();
}

注意:如果您想了解更多信息,可以-pjavap.

下一个 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);
}
于 2020-08-29T16:18:39.090 回答
0

如果你的类有参数构造函数,Java 并不总是给你一个默认的不可见的空构造函数,你必须自己定义空构造函数。

于 2013-08-07T09:13:00.513 回答
-1

从 JPA 标记中,我假设您正在使用 Java bean。每个 bean 都需要具有以下属性:

  1. 其所有主要实例变量的获取器和设置器。

  2. 一个空的构造函数。

  3. 它的所有实例变量最好是private.

因此声明:“每个实体都需要一个空的构造函数”。

于 2013-08-07T09:10:35.377 回答