【優雅代碼】01-lombok精選注解及原理
歡迎關注b站賬号/公衆号【六邊形戰士夏甯】,一個要把各項名額拉滿的男人。該文章已在 github目錄收錄。
螢幕前的大帥比和大漂亮如果有幫助到你的話請順手點個贊、加個收藏這對我真的很重要。别下次一定了,都不關注上哪下次一定。
1.背景介紹
在日常開發中免不了進行一些繁瑣的代碼自動生成,雖然ide的功能已然非常強大但是并不能夠做到動态,lombok可以非常好的解決這個問題。它會在生成class檔案時将其進行編譯成平常所寫的代碼,這裡介紹一些我個人覺得比較好用的注解
2.lombok
先上
官網位址。如果想了解更多注解可以去
https://projectlombok.org/features/all2.1.get/set注解(重要)
此部分注解有@Data、@Getter、@Setter,一般普通Bean對象會使用@Data注解(裡面已經包含另外兩個注解),如果是enum則使用@Getter注解
@Data
static class DataBean {
private String name;
}
// 使用方法如下
public static void DataBeanExample() {
log.info(new DataBean().getName());
}
生成核心代碼如下
static class DataBean {
private String name;
public DataBean() {
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
...
}
2.2.正常構造方法注解(重要)
此部分注解包含@NoArgsConstructor無參構造、@AllArgsConstructor所有參構造、@EqualsAndHashCode、@ToString
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
static class ConstructorBean {
private String name1;
private String name2;
}
// 使用方法如下
public static void ConstructorExample() {
log.info(new ConstructorBean("1", "2").toString());
}
static class ConstructorBean {
private String name1;
private String name2;
public ConstructorBean() {
}
public ConstructorBean(final String name1, final String name2) {
this.name1 = name1;
this.name2 = name2;
}
public boolean equals(final Object o) {
//....
}
protected boolean canEqual(final Object other) {
return other instanceof LombokExample.ConstructorBean;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $name1 = this.name1;
int result = result * 59 + ($name1 == null ? 43 : $name1.hashCode());
Object $name2 = this.name2;
result = result * 59 + ($name2 == null ? 43 : $name2.hashCode());
return result;
}
public String toString() {
return "LombokExample.ConstructorBean(name1=" + this.name1 + ", name2=" + this.name2 + ")";
}
}
2.4.build構造方法(重要)
此部分注解包含@Builder
@Builder
@ToString
static class BuilderBean {
private String name1;
private String name2;
}
// 使用方式如下
public static void BuilderExample() {
log.info(BuilderBean.builder().name1("1").name2("2").build().toString());
}
static class BuilderBean {
private String name1;
private String name2;
BuilderBean(final String name1, final String name2) {
this.name1 = name1;
this.name2 = name2;
}
public static LombokExample.BuilderBean.BuilderBeanBuilder builder() {
return new LombokExample.BuilderBean.BuilderBeanBuilder();
}
public String toString() {
return "LombokExample.BuilderBean(name1=" + this.name1 + ", name2=" + this.name2 + ")";
}
public static class BuilderBeanBuilder {
private String name1;
private String name2;
BuilderBeanBuilder() {
}
public LombokExample.BuilderBean.BuilderBeanBuilder name1(final String name1) {
this.name1 = name1;
return this;
}
public LombokExample.BuilderBean.BuilderBeanBuilder name2(final String name2) {
this.name2 = name2;
return this;
}
public LombokExample.BuilderBean build() {
return new LombokExample.BuilderBean(this.name1, this.name2);
}
public String toString() {
return "LombokExample.BuilderBean.BuilderBeanBuilder(name1=" + this.name1 + ", name2=" + this.name2 + ")";
}
}
}
2.5.鍊式構造方法
此部分注解包含@Accessors,但是因為改寫了set方法的傳回值,有些時候會和其它bean工具類不相容,一般不建議使用
@Accessors(chain = true)
@Setter
@ToString
static class ChainBean {
private String name1;
private String name2;
}
// 使用方式如下
public static void ChainExample() {
log.info(new ChainBean().setName1("1").setName2("2").toString());
}
static class ChainBean {
private String name1;
private String name2;
ChainBean() {
}
public LombokExample.ChainBean setName1(final String name1) {
this.name1 = name1;
return this;
}
public LombokExample.ChainBean setName2(final String name2) {
this.name2 = name2;
return this;
}
...
}
2.6.日志注解(重要)
此部分注解包含@Slf4j,其它的注解都不重要,這個會自動根據引入包進行選擇
@Slf4j
public class LombokExample {
public static void main(String[] args) {
log.info("123");
}
}
private static final Logger log = LoggerFactory.getLogger(LombokExample.class);
2.7.關閉流
@Cleanup,這個可以幫助關閉流,需要注意的是需要對其捕獲IO異常。雖然不錯,但是有了trywith的寫法以後就用的不多了。
public static void CloseExample() throws FileNotFoundException {
try {
@Cleanup FileInputStream fileInputStream = new FileInputStream("");
} catch (IOException e) {
}
}
可以看到會幫我們進行close。不過并沒有在finally裡面不建議使用
public static void CloseExample() throws FileNotFoundException {
try {
FileInputStream fileInputStream = new FileInputStream("");
if (Collections.singletonList(fileInputStream).get(0) != null) {
fileInputStream.close();
}
} catch (IOException var1) {
}
}
這裡推薦try-with-resources寫法
public static void CloseExample2() {
try (FileInputStream fileInputStream = new FileInputStream("")) {
log.info("123");
} catch (IOException e) {
}
}
可以看到是在finally裡面關閉了流,并且各種判斷非常全面
public static void CloseExample2() {
try {
FileInputStream fileInputStream = new FileInputStream("");
Throwable var1 = null;
try {
log.info("123");
} catch (Throwable var11) {
var1 = var11;
throw var11;
} finally {
if (fileInputStream != null) {
if (var1 != null) {
try {
fileInputStream.close();
} catch (Throwable var10) {
var1.addSuppressed(var10);
}
} else {
fileInputStream.close();
}
}
}
} catch (IOException var13) {
}
}
2.8.異常注解
在捕獲編譯時異常的時候比較好用,但是現在越來越多的工具類都對編譯異常捕獲了,它的出場機會并不多
@SneakyThrows({IOException.class})
public static void ExceptionExample() {
CloseExample();
}
唯一的功能就是捕獲編譯時異常,不用手動去寫
public static void ExceptionExample() {
try {
CloseExample();
} catch (IOException var1) {
throw var1;
}
}
3.delombok
如果後面不想用注解則需要使用delombok
- 方法一
在新版的idea中refactor->delombok已經內建了delombok,可以直接還原算是比較友善的

- 方法二
java -jar lombok.jar delombok src -d src-delomboked
注意替換包名