天天看點

Lombok實驗室之@Accessors使用一. 為什麼要用@Accessors?二. @Accessors如何使用?三. @Accessors源碼四. 特别說明

一. 為什麼要用@Accessors?

通常,在建立對象的時候,我們使用構造函數為成員變量指派。一個對象的初始化,參數有時候不固定,是以就有了參數不同的構造函數。但是,如果一個類的成員變量很多,那麼就有可能産生很多的構造函數。當然,你可以使用無參的構造函數先建立一個對象,再去調用setter方法為需要初始化的變量指派。這樣做的弊端很明顯,就是一行行的setter方法費時費力。不然,也不會有不同的構造函數。但是,即使有了很多不同的構造函數,對于建立一個複雜的對象(擁有很多成員變量)也很棘手。因為在new的過程中,當我們傳入構造函數的參數很多,會出現這樣一種情況——不知道這個參數具體是幹什麼的。這時候構造函數,似乎不如setter方法那樣清晰明了,因為setter方法名可以幫助我們了解這個參數具體的作用。

那麼有沒有辦法,讓我們在建立對象的過程中,既能擁有多個構造函數的參數不确定的特點,同時又能夠像setter方法那樣知道每個參數具體的作用呢?其實這就是我們常說的建造者模式,在《Lombok之@Builder使用》中,我們知道了@Builder可以實作這樣的功能。不過,它也有點缺陷——無法在建立對象後繼續使用鍊式指派。幸運的是,Lombok出了一個@Accessors注解,完美地解決了這個問題,它可以讓你随時随地使用鍊式指派。

Lombok實驗室之@Accessors使用一. 為什麼要用@Accessors?二. @Accessors如何使用?三. @Accessors源碼四. 特别說明

二. @Accessors如何使用?

在@Accessors的官方文檔中,對于@Accessors的總結是——A more fluent API for getters and setters.意為:面向getter和setter的更流暢的API。是以,@Accessors是配合@Getter/@Setter注解一起使用的。代碼如下:

@Getter
@Setter
@Accessors(fluent = true, chain = true)
public class Student {

    private String name;

    private Integer age;

}
           

反編譯後的代碼如下:

public class Student {
    private String name;
    private Integer age;

    public Student() {
    }

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

    public Integer age() {
        return this.age;
    }

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

    public Student age(Integer age) {
        this.age = age;
        return this;
    }
}
           

可以看到,所有的getter和setter方法都使用了變量名的作為方法名。setter方法的傳回值全是Student類型。代碼示範:

Lombok實驗室之@Accessors使用一. 為什麼要用@Accessors?二. @Accessors如何使用?三. @Accessors源碼四. 特别說明

三. @Accessors源碼

package lombok.experimental;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * A container for settings for the generation of getters and setters.
 * <p>
 * Complete documentation is found at <a href="https://projectlombok.org/features/experimental/Accessors" target="_blank" rel="external nofollow" >the project lombok features page for &#64;Accessors</a>.
 * <p>
 * Using this annotation does nothing by itself; an annotation that makes lombok generate getters and setters,
 * such as {@link lombok.Setter} or {@link lombok.Data} is also required.
 */
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Accessors {
	/**
	 * If true, accessors will be named after the field and not include a {@code get} or {@code set}
	 * prefix. If true and {@code chain} is omitted, {@code chain} defaults to {@code true}.
	 * <strong>default: false</strong>
	 * 
	 * @return Whether or not to make fluent methods (named {@code fieldName()}, not for example {@code setFieldName}).
	 */
	boolean fluent() default false;
	
	/**
	 * If true, setters return {@code this} instead of {@code void}.
	 * <strong>default: false</strong>, unless {@code fluent=true}, then <strong>default: true</strong>
	 * 
	 * @return Whether or not setters should return themselves (chaining) or {@code void} (no chaining).
	 */
	boolean chain() default false;
	
	/**
	 * If present, only fields with any of the stated prefixes are given the getter/setter treatment.
	 * Note that a prefix only counts if the next character is NOT a lowercase character or the last
	 * letter of the prefix is not a letter (for instance an underscore). If multiple fields
	 * all turn into the same name when the prefix is stripped, an error will be generated.
	 * 
	 * @return If you are in the habit of prefixing your fields (for example, you name them {@code fFieldName}, specify such prefixes here).
	 */
	String[] prefix() default {};
}

           
  • 元注解:@Target({ElementType.TYPE, ElementType.FIELD}),@Retention(RetentionPolicy.SOURCE)
  • 注解屬性:fluent注解預設值為false,則保留getter和setter方法前面的get和set字首。如果為true,則不保留字首,直接使用變量名作為方法名,也就構成了方法的重載。

    值得注意的是,當fluent為true時,chain注解屬性的值就自動設定成了true。chain的預設值是false,意味不啟用鍊式指派,也就是setter方法傳回體為void。

    prefix注解屬性處理變量名字首的,隻有擁有字首的變量才會生成getter/setter方法,而且它的比對原則是——比對到的變量去掉字首後第一個字母不能是小寫。通俗地說就是,運用駝峰命名規則去比對。

四. 特别說明

本文已經收錄在Lombok注解系列文章總覽中,并繼承上文中所提的特别說明。

源碼位址:gitee