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


    转自:https://blog.csdn.net/54powerman/article/details/72516755

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

  • 相关阅读:
    Facebook – Facebook Page Embed
    HTML & CSS – Styling List
    json转换struct结构体
    ICLR 2022 | 阿里提出目标检测新范式GiraffeDet:轻骨干、重Neck
    cuda10.1+cudnn7.5.0+tensorrt5.1
    cuda加速第一个例子
    卡尔曼滤波的原理(Python实现)
    CUDA入门(一):CUDA11.0+VS2019+WIN10环境配置
    匹配 基于深度学习实现以图搜图功能
    标注>>分割半自动
  • 原文地址:https://www.cnblogs.com/sharpest/p/7888954.html
Copyright © 2020-2023  润新知