Lombok使用注意事项
花门楼前见秋草,岂能贫贱相看老。
注解
@EqualsAndHashCode(callSuper = true)
当标注@Data的类继承其它( 非Object ) 时IEAD提示
生成 equals/hashCode 实现,但即使此类未扩展 java.lang.Object,也不调用超类。如果这是有意为之,请在您的类型中添加 ‘(callSuper=false)’
父类
@Data
public abstract class AbstractAuditBase {
private Instant createdTime;
private Instant updatedTime;
private String createdBy;
private String updatedBy;
}
子类
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Balance extends AbstractAuditBase implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private BigDecimal balance;
public Balance( String name, BigDecimal balance) {
this.name = name;
this.balance = balance;
}
public Balance(Integer id, BigDecimal balance) {
this.id = id;
this.balance = balance;
}
}
测试
@Test
public void test1() {
Balance balance1 = new Balance(1, BigDecimal.ONE);
Balance balance2 = new Balance(1, BigDecimal.TEN);
Balance balance3 = new Balance(1, BigDecimal.ONE);
System.out.printf("balance1: %s\t balance2: %s\t equals:%s\n", balance1, balance2, balance1.equals(balance2));
System.out.printf("balance1: %s\t balance3: %s\t equals:%s\n", balance1, balance3, balance1.equals(balance3));
balance1.setCreatedBy("1");
balance3.setCreatedBy("3");
System.out.printf("balance1: %s\t balance3: %s\t equals:%s\n", balance1, balance3, balance1.equals(balance3));
}
输出
balance1: Balance(id=1, name=null, balance=1) balance2: Balance(id=1, name=null, balance=10) equals:false
balance1: Balance(id=1, name=null, balance=1) balance3: Balance(id=1, name=null, balance=1) equals:true
balance1: Balance(id=1, name=null, balance=1) balance3: Balance(id=1, name=null, balance=1) equals:true
此时 Balance 类生成的字节码中equals方法,并没有调用父类的字段进行比较。
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Balance)) {
return false;
} else {
Balance other = (Balance)o;
if (!other.canEqual(this)) {
return false;
} else {
label47: {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id == null) {
break label47;
}
} else if (this$id.equals(other$id)) {
break label47;
}
return false;
}
...
}
}
}
根据 IDEA 提示,在 Balance 上添加注解
运行测试
balance1: Balance(id=1, name=null, balance=1) balance2: Balance(id=1, name=null, balance=10) equals:false
balance1: Balance(id=1, name=null, balance=1) balance3: Balance(id=1, name=null, balance=1) equals:true
balance1: Balance(id=1, name=null, balance=1) balance3: Balance(id=1, name=null, balance=1) equals:false
Balance 生成的字节码 equal 方法
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Balance)) {
return false;
} else {
Balance other = (Balance)o;
if (!other.canEqual(this)) {
return false;
} else if (!super.equals(o)) { //调用了父类的equal方法
return false;
} else {
....
}
}
总结
@EqualsAndHashCode 基于相关字段为所有对象继承的equals和hashCode方法生成实现。
@Data注解包含了该注解,并且默认不调用父类equals
boolean callSuper() default false;
因此在使用@Data注解时需要注意被标注的类是否继承了非 Object 类,子类的equals是否需要调用父类 equals()
- 是:@EqualsAndHashCode(callSuper = true)
- 否:@EqualsAndHashCode(callSuper = false)
同理 @ToString 也可以根据需要是否调用父类方法 @ToString(callSuper = true)
balance1: Balance(super=AbstractAuditBase(createdTime=null, updatedTime=null, createdBy=null, updatedBy=null), id=1, name=null, balance=1)
Getter、Setter方法生成
使用 @Data,@Getter,@Setter时需要注意布尔字段。
@Data
public class User {
private String id;
private boolean success;
private boolean isOk;
private Boolean failure;
}
字节码中生成的方法。
public class User {
private String id;
private boolean success;
private boolean isOk;
private Boolean failure;
public String getId() {
return this.id;
}
public boolean isSuccess() {
return this.success;
}
public boolean isOk() {
return this.isOk;
}
public Boolean getFailure() {
return this.failure;
}
public void setId(String id) {
this.id = id;
}
public void setSuccess(boolean success) {
this.success = success;
}
public void setOk(boolean isOk) {
this.isOk = isOk;
}
public void setFailure(Boolean failure) {
this.failure = failure;
}
public boolean equals(Object o) {
...
}
protected boolean canEqual(Object other) {
return other instanceof User;
}
public int hashCode() {
...
}
public String toString() {
String var10000 = this.getId();
return "User(id=" + var10000 + ", success=" + this.isSuccess() + ", isOk=" + this.isOk() + ", failure=" + this.getFailure() + ")";
}
public User() {
}
}
总结
- 对于布尔的基本类型 “get” 方法 为 “is”+“字段名称”;并且字段名前缀已包含 “is” 时,生成的方法中会自动简化。
- 对于布尔包装类型,“get”方法不变。
- 推荐:对于 JavaBean 的字段类型可一律采用包装类型(另一方面原因:包装类型默认值为 null,可以空值阻断)。
@Slf4j日志打印
对 ‘printStackTrace()’ 的调用可能应当替换为更可靠的日志
e.printStackTrace() 和 System.out.print() 一样是不会把信息输出到日志文件的。
解决措施:
使用 log.error(e.getMessage(),e); 将错误信息通过日志对象输出到日志文件。
版权声明:如无特别声明,本站收集的文章归 HuaJi66/Others 所有。 如有侵权,请联系删除。
联系邮箱: GenshinTimeStamp@outlook.com
本文标题:《 Lombok使用注意事项 》