lombok系列3:lombok的實驗類特性

lombok除了已經推薦使用的基本功能,還維護了一個創新型的註解,有些功能有違常規對java認知,或者只支持eclipse,其他IDE支持有問題,甚至某些環境完全不可用。因此沒有正式使用。

但是的確很有創意,這些註解已經在jar中提供,只不過它是歸在”lombok.experimental.” 包中;而基本功能在”lombok.” 包中。

@Accessors

定製流暢的訪問器。

@Accessors(chain=true)

鏈式訪問,該註解設置chain=true,生成setter方法返回this,代替了默認的返回void。

package com.pollyduan;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain=true)
public class User {
    private Integer id;
    private String name;
    private Integer age;

    public static void main(String[] args) {
        User user=new User().setAge(31).setName("pollyduan");
        System.out.println(user);
    }

}

@Accessors(fluent = true)

chain=true類似,區別在於getter和setter不帶set和get前綴。

package com.pollyduan;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(fluent=true)
public class User {
    private Integer id;
    private String name;
    private Integer age;

    public static void main(String[] args) {
        User user=new User().age(31).name("pollyduan");
        System.out.println(user);
    }

}

@Accessors(prefix = “f”)

沒什麼意思,直接看代碼。

package com.pollyduan;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(prefix = "f")
public class User {
    private String fName = "Hello, World!";

    public static void main(String[] args) {
        User user=new User();
        user.setName("pollyduan");//注意方法名
        System.out.println(user);
    }

}

@ExtensionMethod

爲已經存在的類增加方法。

它可以達到擴展已有類的方法。它之所以作爲實驗特性,是因爲:

在代碼風格上衝擊較大;
它只是在編碼時看起來擴展了普通類的方法,但lombok目前還沒有好的辦法讓運行時其他類引用;
elipse可用,netbeans完全沒用;
合法性待考證。

來個例子吧。我們知道我們要對java.util.Date對象進行格式化,通常使用SimpleDateFormat對象來實現,我們能不能給Date對象增加一個format方法呢?come on…

工具類:

package com.pollyduan;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Extensions {
    public static String format(Date date){
        SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(date);
    }
}

應用類:

package com.pollyduan;

import java.text.SimpleDateFormat;
import java.util.Date;

import lombok.Data;
import lombok.experimental.ExtensionMethod;

@Data
@ExtensionMethod({java.util.Arrays.class, Extensions.class,SimpleDateFormat.class})
public class ExtensionMethodDemo {
    private void test() {
        Date date=new Date();
        String d=date.format();
        System.out.println(d);
    }
    public static void main(String[] args) {
        new ExtensionMethodDemo().test();
    }

}

實現依據:

假設被擴展類爲A,擴展工具類爲B,那麼就需要在類B中定義個static的方法,該方法有一個參數,類型爲A。

然後,在A中添加@ExtensionMethod(B.class) 註解即可。

一個泛型的例子:

//工具方法
public static <T> T or(T obj, T ifNull) {
   return obj != null ? obj : ifNull;
}

//使用
String str=null;
System.out.pritnln(str.or("default_value"));//default_value
str="abcd";
System.out.pritnln(str.or("default_value"));//abcd

@FieldDefaults

設置缺省的字段修飾符。

非常亂,看不下去了,上代碼。

package com.pollyduan;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.experimental.NonFinal;
import lombok.experimental.PackagePrivate;

@AllArgsConstructor
@FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE)
public class FieldDefaultsExample {
    public final int a;
    int b;
    @NonFinal int c;
    @PackagePrivate int d;
}

缺省爲private final

如果不想使用缺省值,可顯式標註,或使用NonFinal取消final。

以上類,相當於:

package com.pollyduan;

public class FieldDefaultsExample {
    public final int a;//明確定義的,不受影響
    private final int b;//未明確定義的,使用註解的private final
    private int c;//指定了NonFinal則只保留private
    final int d;//執行了PackagePrivate,表示使用包私有,即default可見修飾符,只保留final

    public FieldDefaultsExample(int a, int b, int c, int d) {
        super();
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }
}

@Delegate

代理方法。

package com.pollyduan;

import java.util.ArrayList;
import java.util.Collection;

import lombok.experimental.Delegate;

public class User {

    private interface SimpleCollection {
        boolean add(String item);
        boolean remove(Object item);
    }

    @Delegate(types = SimpleCollection.class)
    private final Collection<String> collection = new ArrayList<String>();

    public static void main(String[] args) {
         User user=new User();
         user.add("item1");//實際上加到collection中去了
    }

}

@Wither

package com.pollyduan;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.ToString;
import lombok.experimental.Wither;

@AllArgsConstructor
@ToString
public class User {
    @Wither
    private Integer id;
    @NonNull
    @Wither(AccessLevel.PROTECTED)
    private String name;

    public static void main(String[] args) {
         User user=new User(1001,"pollyduan")
                 .withId(123)
                 .withName("tom");
         System.out.println(user);
    }

}

執行輸出:User(id=123, name=tom)

沒明白這種模式有啥用,必須全參構造,然後通過with改。。。。

@OnX

亂呀,等腦子清醒再說吧。

@UtilityClass

工具類。

自動將所有域對象修改爲static;而且自動創建一個私有的構造器:

private UtilityClassExample() {
 throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

@Helper

不知所謂。

package com.pollyduan;

import lombok.experimental.Helper;

public class HelperExample {
    int someMethod(int arg1) {
        int localVar = 5;

        @Helper
        class Helpers {
            int helperMethod(int arg) {
                return arg + localVar;
            }
        }

        return helperMethod(10);
    }
}

相當於:

package com.pollyduan;

public class HelperExample {
    int someMethod(int arg1) {
        int localVar = 5;

        class Helpers {
            int helperMethod(int arg) {
                return arg + localVar;
            }
        }

        return new Helpers().helperMethod(10);//就這點區別,毛用?
    }
}

小結

想法很好,也許哪一天可被接納,或者被借鑑。

總結起來,有幾個個人比較關注,比如:@Delegate 、@ExtensionMethod、@Accessors;在某些環境下,可嘗試使用。

發佈了150 篇原創文章 · 獲贊 119 · 訪問量 73萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章