繁体   English   中英

Java 实体 - 为什么我需要一个空的构造函数?

[英]Java entity - why do I need an empty constructor?

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

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

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

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

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

例子:

@Entity
public class MyEntity implements Serializable {

   @Id
   private String str;

   public MyEntity(){}

   //here getter and setter
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

其实没必要写。 默认情况下,您拥有它。 有时你可以创建private构造函数来防止用户使用默认的

public class MyClass{

private MyClass(){} 

} 

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

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

所有的答案都很好。

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

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

注意:如果您需要更多信息,可以在javap上使用-p标志。

下一个 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);
}

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

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

  1. 其所有主要实例变量的 getter 和 setter。

  2. 一个空的构造函数。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM