你還在 Java 代碼中寫 set/get 方法?趕快試試這款插件吧!

前言

what?你的 Java 代碼中還充斥着大量的 set/get 方法?java

咱們在剛開始學習 Java 語言的時候講過,面向對象的三大特徵就是封裝,繼承,和多態。在 Java 中,要保證封裝性,須要將成員變量私有化,對外提供 set/get 方法來訪問,雖然如今的 IDE,像 eclipse,IDEA都提供了快捷鍵,來生成 set/get 方法。app

可是在作項目的時候,一個 JavaBean 每每會有不少的成員變量,一個變量對應兩個方法,若是有10幾個成員變量,那麼會對應20多個方法,也許還要去寫構造器、equals 等方法,並且須要維護。這樣一來,會使代碼變得很是冗餘,這些顯得很冗長也沒有太多技術含量,一旦修改屬性,就容易出現忘記修改對應方法的失誤。eclipse

我在看大佬的項目的源碼的時候,看到他們的代碼中都沒有 set/get 方法,取而代之的是在 JavaBean 上標註的註解,我感到很是的好奇,原來他們是用了一種叫作 Lombok 的插件,便去詳細瞭解了這個插件。maven

Lombok 背景介紹

官方介紹以下:ide

Project Lombok makes java a spicier language by adding 'handlers' that know how to build and compile simple, boilerplate-free, not-quite-java code.學習

大體意思是 Lombok 經過增長一些「處理程序」,可讓 Java 變得簡潔、快速。ui

Lombok 使用方法

Lombok 能經過註解的方式,在編譯時自動爲屬性生成構造器、getter/setter、equals、hashcode、toString 方法。出現的神奇就是在源碼中沒有 getter 和 setter 方法,可是在編譯生成的字節碼文件中有 getter 和 setter 方法。這樣就省去了手動重建這些代碼的麻煩,使代碼看起來更簡潔些。this

Lombok 的使用跟引用 jar 包同樣,能夠在官網(https://projectlombok.org/download)下載 jar 包,也能夠使用 maven 添加依賴:spa

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
    <scope>provided</scope>
</dependency>

注意:
第一次使用 Lombok 插件須要作以下幾步配置插件

1.將 Lombok 插件安裝到 IDEA

file -> setting

圖片

選中 Plugins,搜索 Lombok,點擊 Install

圖片

2.選擇默認的編譯方式爲 javac,由於 eclipse 是不支持 Lombok 的編譯方式的,javac 支持 Lombok 的編譯方式。

圖片

3.打開註解生成器 Enable annotation processing

圖片

再次注意:

IntelliJ IDEA 2019.2(也就是我用的版本)默認是不支持 Lombok 插件的,須要去

https://plugins.jetbrains.com/plugin/6317-lombok/versions

下載對應版本的插件,而後手動引入,在 IDEA 中選擇 File -> Setting -> plugins 找到 Install Plugin from Disk…(注意版本不一樣位置可能有所差別)

圖片

接下來咱們來分析 Lombok 中註解的具體用法

@Data

@Data 註解在類上,會爲類的全部屬性自動生成 setter/getter、equals、canEqual、hashCode、toString 方法,如爲 final 屬性,則不會爲該屬性生成 setter 方法。

好比咱們寫一個學生類

@Data
public class Student {
    private String name;
    private Integer age;
    private Integer id;
    private String major;
}

圖片

這樣就能夠調用 set/get 方法了。

@Getter/@Setter

若是以爲@Data 太過殘暴(由於@Data 集合了@ToString、@EqualsAndHashCode、@Getter/@Setter、@RequiredArgsConstructor 的全部特性)不夠精細,能夠使用@Getter/@Setter 註解,此註解在屬性上,能夠爲相應的屬性自動生成 set/get 方法。

public class Student {
    @Setter private String name;
    private Integer age;
    private Integer id;
    private String major;

    public static void main(String[] args) {
        Student stu = new Student();
        stu.setName("Mr.ml");
    }
}

@NonNull

該註解用在屬性或構造器上,Lombok 會生成一個非空的聲明,可用於校驗參數,能幫助避免空指針。

public class Student {
    @Setter private String name;
    private Integer age;
    private Integer id;
    private String major;

    public Student(@NonNull String name) {
        this.name = name;
    }
}

@Cleanup

該註解能幫助咱們自動調用 close() 方法,很大的簡化了代碼。

public class CleanupExample {
    public static void main(String[] args) throws IOException {
        @Cleanup InputStream in = new FileInputStream(args[0]);
        @Cleanup OutputStream out = new FileOutputStream(args[1]);
        byte[] b = new byte[10000];
        while (true) {
            int r = in.read(b);
              if (r == -1break;
              out.write(b, 0, r);
        }
      }
}

@EqualsAndHashCode

默認狀況下,會使用全部非靜態(non-static)和非瞬態(non-transient)屬性來生成 equals 和 hashCode,也能經過 exclude 註解來排除一些屬性。

@EqualsAndHashCode(exclude={"id""shape"})
public class EqualsAndHashCodeExample {
    private transient int transientVar = 10;
    private String name;
    private double score;
    private Shape shape = new Square(510);
    private String[] tags;
    private int id;

    public String getName() {
        return this.name;
    }

    @EqualsAndHashCode(callSuper=true)
    public static class Square extends Shape {
        private final int width, height;

        public Square(int width, int height) {
            this.width = width;
            this.height = height;
        }
    }
}

@ToString

類使用@ToString 註解,Lombok 會生成一個 toString() 方法,默認狀況下,會輸出類名、全部屬性(會按照屬性定義順序),用逗號來分割。

經過將 includeFieldNames 參數設爲 true,就能明確的輸出 toString() 屬性。這一點是否是有點繞口,經過代碼來看會更清晰些。

@ToString(exclude="id")
public class ToStringExample {
    private static final int STATIC_VAR = 10;
    private String name;
    private Shape shape = new Square(510);
    private String[] tags;
    private int id;

    public String getName() {
        return this.getName();
    }

    @ToString(callSuper=true, includeFieldNames=true)
    public static class Square extends Shape {
        private final int width, height;

        public Square(int width, int height) {
            this.width = width;
            this.height = height;
        }
    }
}

@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor
無參構造器、部分參數構造器、全參構造器。Lombok無法實現多種參數構造器的重載。

@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T{
    private int x, y;
    @NonNull private T description;

    @NoArgsConstructor
    public static class NoArgsExample {
        @NonNull private String field;
    }
}

圖片

相關文章
相關標籤/搜索