首页 > 代码库 > lombok系列3:lombok的实验类特性

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_valuestr="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@ToStringpublic 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;在某些环境下,可尝试使用。

lombok系列3:lombok的实验类特性