Java 使用 Lombok 的显式构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3864391/
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
Explicit constructor using Lombok?
提问by FinalArt2005
I'm rewriting some messy code that manages a database, and saw that the original programmer created a class mapped to the database like so:
我正在重写一些管理数据库的凌乱代码,并看到原始程序员创建了一个映射到数据库的类,如下所示:
(I've removed unnecessary code that has no purpose in this question)
(我已经删除了在这个问题中没有意义的不必要的代码)
@Entity
@Data
@EqualsAndHashCode(callSuper = false, of = { "accessionCode", "header", "date" })
@SuppressWarnings("PMD.UnusedPrivateField")
public class PDBEntry implements Serializable {
@Id
@NaturalId
@NotEmpty
@Length(max = 4)
private String accessionCode;
@NaturalId
@NotEmpty
private Date date;
@NaturalId
// We allow for the header to be 'null'
private String header;
private Boolean isValidDssp;
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdated = new Date(System.currentTimeMillis());
protected PDBEntry(){}
public PDBEntry(String accessionCode, String header, Date date){
this.accessionCode = accessionCode;
this.header = header;
this.date = date;
}
}
I am still a beginner at Hibernate and using Lombok, but wouldn't this do the same thing and wouldn't Lombok automatically create the needed constructor for you?
我仍然是 Hibernate 的初学者并使用 Lombok,但这不会做同样的事情,Lombok 不会自动为您创建所需的构造函数吗?
@Entity
@Data
@SuppressWarnings("PMD.UnusedPrivateField")
public class PDBEntry implements Serializable {
@Id
@NaturalId
@NotEmpty
@NonNull
@Length(max = 4)
private String accessionCode;
@NaturalId
@NotEmpty
@NonNull
private Date date;
@NaturalId
// We allow for the header to be 'null'
private String header;
private Boolean isValidDssp;
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdated = new Date(System.currentTimeMillis());
}
Also, the original programmer of this code says he allows for the header to be 'null', yet he explicitly created a constructor that needs a value for header. Am I missing something or is this a bit contradictory?
此外,这段代码的原始程序员说他允许标头为“空”,但他明确创建了一个需要标头值的构造函数。我错过了什么还是有点矛盾?
采纳答案by Tim
Have a look at @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
.
看看@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
。
The constructor behavior of @Data
is like @RequiredArgsConstructor
:
的构造函数行为@Data
类似于@RequiredArgsConstructor
:
@RequiredArgsConstructor generates a constructor with 1 parameter for each field that requires special handling. All final fields get a parameter, as well as any fields that are marked as @NonNull that aren't initialized where they are declared.
@RequiredArgsConstructor 为每个需要特殊处理的字段生成一个带有 1 个参数的构造函数。所有最终字段都获得一个参数,以及任何标记为 @NonNull 且未在声明位置初始化的字段。
Given that none of your fields are either final
or @NonNull
, this will result in a no-argument constructor. However, this is not the most expressive way to achieve this behavior.
鉴于您的任何字段都不是final
或@NonNull
,这将导致无参数构造函数。但是,这并不是实现此行为的最具表现力的方式。
What you'll probably want in this case is a @NoArgsConstructor
(optionally combined with a @AllArgsConstructor
), to clearly communicate the intended behavior, as is also indicated in the documentation:
在这种情况下,您可能想要的是一个@NoArgsConstructor
(可选地与 a 结合@AllArgsConstructor
),以清楚地传达预期的行为,如文档中所示:
Certain java constructs, such as hibernate and the Service Provider Interface require a no-args constructor. This annotation is useful primarily in combination with either @Data or one of the other constructor generating annotations.
某些 java 构造,例如 hibernate 和服务提供者接口,需要无参数构造函数。此注释主要与 @Data 或其他生成注释的构造函数之一结合使用。
回答by DeliveryNinja
That bit is contradictory you're right. I've not used Lombok before but with hibernate if you want to be able to create a bean and persist you need the default constructor as given above as far I was aware. It uses Constructor.newInstance() to instantiate new objects.
那一点是矛盾的,你是对的。我以前没有使用过 Lombok,但是如果你想能够创建一个 bean 并持久化,你需要使用上面给出的默认构造函数。它使用 Constructor.newInstance() 来实例化新对象。
Here is some hibernate documentation which goes into more detail.
这是一些更详细的休眠文档。
回答by Jules Martel
If you are using @Data with a @NonNull field and still want a noargs-constructor, you might wanna try to add all 3 annotation together
如果您使用带有 @NonNull 字段的 @Data 并且仍然想要一个 noargs-constructor,您可能想尝试将所有 3 个注释添加在一起
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
Apparently an old intelliJbug which I did replicate in Eclipse Kepler and lombok v0.11.4
显然是我在 Eclipse Kepler 和 lombok v0.11.4 中复制的一个旧的intelliJ错误
回答by zee
@NoArgsConstructor,
@RequiredArgsConstructor,
@AllArgsConstructor
Generate constructors that take no arguments, one argument per final / non-null field, or one argument for every field. Read this lombok-project
生成不带参数的构造函数,每个最终/非空字段一个参数,或每个字段一个参数。阅读这个lombok 项目
@Data
@RequiredArgsConstructor /*Duplicate method Someclass() in type Someclass*/
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true) /*Duplicate method Someclass() in type Someclass*/
@Entity
public class Someclass {
@Id
private String id;
private String name;
private Type type;
public static enum Type { X , Y, Z}
}
Fixed it by making member variables final
通过将成员变量设为 final 来修复它
@Data
@RequiredArgsConstructor
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)
@Entity
public class Someclass {
@Id
private final String id;
private final String name;
private final Type type;
public static enum Type { X , Y, Z}
}