公司项目里面用了 lombok,感觉这个东西真是个好东西,然后公司也用的简单,所以也没仔细看文档就开始想当然的用了,然后就悲剧了,今天就记录一下这件事,写一下经验教训,具体怎么用,大家可以看最后的参考。
lombok 有一个很好用的注解:@Data,当时以为这个注解就是相当于:@Getter和@Setter,所以有一次要重写 equals 和 hashcode 方法,然后就让 IDE 自动生成了,当时也没仔细看生成的是什么样子,然后就发现了 bug,仔细一看生成的 equals 方法原来是这样的:


package cn.bridgeli.demo;

import lombok.Data;

import java.util.Objects;

/**  
* Created by bridgeli on 2018/2/25.  
*/  
@Data  
public class LomBokTest {  
private Integer id;  
private String username;

@Override  
public boolean equals(Object o) {  
if (this == o) {  
return true;  
}  
if (o == null || getClass() != o.getClass()) {  
return false;  
}  
if (!super.equals(o)) {  
return false;  
}  
LomBokTest that = (LomBokTest) o;  
return Objects.equals(id, that.id);  
}

@Override  
public int hashCode() {  
return Objects.hash(super.hashCode(), id);  
}  
}

当时还以为是 idea 的 bug,因为是 idea 自动生成的,之前用 eclipse 自动生成从没问题,eclipse 自动生成的是这样的:


package cn.bridgeli.demo;

import lombok.Data;

/**  
* Created by bridgeli on 2018/2/25.  
*/  
@Data  
public class LomBokTest {  
private Integer id;  
private String username;

@Override  
public int hashCode() {  
final int prime = 31;  
int result = 1;  
result = prime * result + ((id == null) ? 0 : id.hashCode());  
return result;  
}

@Override  
public boolean equals(Object obj) {  
if (this == obj) {  
return true;  
}

if (obj == null) {  
return false;  
}  
if (getClass() != obj.getClass()) {  
return false;  
}  
LomBokTest other = (LomBokTest) obj;  
if (id == null) {  
if (other.id != null) {  
return false;  
}  
} else if (!id.equals(other.id)) {  
return false;  
}  
return true;  
}

}

然后看了他们俩生成的区别:idea 生成的有一行:super.equals(o),这就明显了,当时还以为 bug 了。然后就用了 eclipse 生成的这种,后来感觉不应该啊,问了朋友,朋友说用 idea 从没遇到过,自己就感觉很好奇,突然想到是不是因为 lombok 引起的,然后就不用 lombok 生成一次试试,结果是这样的:


package cn.bridgeli.demo;

import java.util.Objects;

/**  
* Created by bridgeli on 2018/2/25.  
*/  
public class LomBokTest {  
private Integer id;  
private String username;

public Integer getId() {  
return id;  
}

public void setId(Integer id) {  
this.id = id;  
}

public String getUsername() {  
return username;  
}

public void setUsername(String username) {  
this.username = username;  
}

@Override  
public boolean equals(Object o) {  
if (this == o) {  
return true;  
}  
if (o == null || getClass() != o.getClass()) {  
return false;  
}  
LomBokTest that = (LomBokTest) o;  
return Objects.equals(id, that.id);  
}

@Override  
public int hashCode() {  
return Objects.hash(id);  
}  
}

好么,果然没问题,然后意识到可能是 lombok 的问题,但是感觉这么好的东西,不应该啊,所以就查一下,这个东西到底怎么了,然后就看到原来 @Data 这个注解的含义是:相当于是@ToString、@EqualsAndHashCode、@Getter、@Setter效果的集合,已经自动生成了 equals 和 hashcode 方法,不过是全字段的,如果自定义字段可以再次添加:


@EqualsAndHashCode(of = {"id"}, callSuper = false)

其中 of 中就是参与自动生成 equals 和 hashcode 方法的字段。

从这次的小小 bug 中,我的感悟是:有些东西,如果仅仅流于表明,可能平时不会有什么问题,但是说不定什么时候就会采坑,所以需要我们对待技术在使用的时候,刚开始可以先用,但有时间最好一定要搞好知其所以然,这样才能减少使用的过程中犯错。最后也给大家推荐一下这个小东西,感觉真的是特别好用的一个东西,具体用法大家可以看这篇文章:http://blog.csdn.net/jackie_xiaonan/article/details/24869951,感觉写的挺详细,就不做赘述了。