天天看點

【優雅代碼】01-lombok精選注解及原理【優雅代碼】01-lombok精選注解及原理

【優雅代碼】01-lombok精選注解及原理

歡迎關注b站賬号/公衆号【六邊形戰士夏甯】,一個要把各項名額拉滿的男人。該文章已在 github目錄

收錄。

螢幕前的大帥比和大漂亮如果有幫助到你的話請順手點個贊、加個收藏這對我真的很重要。别下次一定了,都不關注上哪下次一定。

1.背景介紹

在日常開發中免不了進行一些繁瑣的代碼自動生成,雖然ide的功能已然非常強大但是并不能夠做到動态,lombok可以非常好的解決這個問題。它會在生成class檔案時将其進行編譯成平常所寫的代碼,這裡介紹一些我個人覺得比較好用的注解

2.lombok

先上

官網

位址。如果想了解更多注解可以去

https://projectlombok.org/features/all

2.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,可以直接還原算是比較友善的

【優雅代碼】01-lombok精選注解及原理【優雅代碼】01-lombok精選注解及原理
  • 方法二
java -jar lombok.jar delombok src -d src-delomboked           

注意替換包名