美文网首页
Lombok基础使用

Lombok基础使用

作者: 我知他风雨兼程途径日暮不赏 | 来源:发表于2020-06-25 13:10 被阅读0次
    1. pom.xml依赖及IDEA插件安装
    2. 注解概要说明
    3. 注解详细说明

    引言:Lombok需要安装专门的插件及maven依赖,实现原理也很简单,将.java按照lombok方式进行编译,自动解析对应的注解做出不同的动作,这里不再讨论实现细节,只是简单说明各个稳定版本的注解的使用

    1. pom.xml依赖及IDEA插件安装

    • pom.xml依赖配置:
     <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
    
    • idea 插件安装:


      lombok插件

    2.稳定版本注解概要说明

    注解名称 注解作用域 注解说明
    val 代替变量类型 自适应对应的变量类型,并将变量声明成final类型
    var 代替变量类型 自适应对应变量类型,与val不同不会将变量声明成final类型
    @NonNull 变量 判断该参数是否为null,如果是将抛出lombok异常
    @Cleanup 变量 将自动资源管理,安全调用你的close()方法
    @Getter/@Setter 变量、类 为类的全部字段或者变量生成getter/setter方法
    @ToString 生成toString方法(toString的子注解有些是作用于字段,比如@ToString.Exclude)
    @EqualsAndHashCode 生成equals()和hashcode()的方法
    @NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor 生成无参构造方法,必填参数构造方法,及全参数构造方法
    @Data @ToString、@EqualsAndHashCode、@Getter/@Setter和@RequiredArgsConstructor集合
    @Value 不可变类的@Data注解
    @Builder 生成建造者模式方法
    @SneakyThrows 可用于不实际在方法的throws子句中声明而偷偷抛出已检查异常
    @Getter(lazy=true) 字段 对字段内容赋予一次初值
    @Log 代替繁杂的private static final Logger log = .....

    3.注解详细说明

    3.1 val

    3.1.1 示例

    通过val编写的java代码:

    import java.util.ArrayList;
    import java.util.HashMap;
    import lombok.val;
    
    public class ValExample {
      public String example() {
        val example = new ArrayList<String>();
        example.add("Hello, World!");
        val foo = example.get(0);
        return foo.toLowerCase();
      }
      
      public void example2() {
        val map = new HashMap<Integer, String>();
        map.put(0, "zero");
        map.put(5, "five");
        for (val entry : map.entrySet()) {
          System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
        }
      }
    }
    

    编译结果:

    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
    
    public class ValExample {
      public String example() {
        final ArrayList<String> example = new ArrayList<String>();
        example.add("Hello, World!");
        final String foo = example.get(0);
        return foo.toLowerCase();
      }
      
      public void example2() {
        final HashMap<Integer, String> map = new HashMap<Integer, String>();
        map.put(0, "zero");
        map.put(5, "five");
        for (final Map.Entry<Integer, String> entry : map.entrySet()) {
          System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
        }
      }
    }
    

    需要注意的是:这个特性在NetbBeans中不支持。
    其实我自己编译的时候,并没有final关键字和var效果一致。。。

    3.1.2 支持配置

    lombok.val.flagUsage = [warning|error](默认为不设置)
    如果配置上了val会被标记为(warning|error)

    3.1.3 附属详细说明

    • 对于混合的类型,最常见的是继承类,而非接口类。举个例子:bool?new HashSet() : new ArrayList()是一个混合类型的表达式,它们的结果既可以是AbstractCollection也可以是Serializable,然而类型的推测它是AbstractCollection,因为它是一个类,而Serializable是一个接口类
    • 在模糊不清的例子中,如果初始化表达式是null,推导出来的结果就是java.lang.Object。

    3.2 var

    3.2.1 示例

    和3.1.1一样,不再复述。

    3.2.2 支持配置

    lombok.var.flagUsage = [warning|error](默认为不设置)
    如果配置上了var会被标记为(warning|error)

    3.2.3 附属详细说明

    • var的工作和val很相似,除了var是本地变量,不会被标记为final外。
    • 类型仍然完全是从强制初始化器表达式派生的,任何进一步的赋值(虽然现在是合法的(因为变量不再是final)都不会查看以确定适当的类型。
    • 例如,var x = "Hello";x = Color.RED;是不工作;x的类型将被推断为java.lang.String,因此,x =Color.RED分配将失败。如果x的类型被推断为java.lang.Object这个代码会被编译,但var不会很好的工作。

    3.3 @NonNull

    3.3.1 示例

    • 代码片段1:直接作用于函数的变量上判断非空
    • 代码片段2:结合@Data注解,如果被标记为@NonNull注解的字段将会成为必填字段,在构造函数中如果该字段为null抛出lombok异常。
      代码片段1:
    package study.lombok;
    
    import lombok.Getter;
    import lombok.NonNull;
    import lombok.Setter;
    
    /**
     * @Author LynHB
     * @Description : Lombok @NonNull注解测试
     * @Date 20:23 2020/6/24
     **/
    public class NonNullAnnotation {
    
        @Getter
        @Setter
        public class Person{
            private String name;
            private int age;
        }
    
        public void testPersonIsNull(@NonNull Person person){
            System.out.println(person.getName());
        }
    
        public static void  main(String[] args){
            NonNullAnnotation nonNullAnnotation = new NonNullAnnotation();
            nonNullAnnotation.testPersonIsNull(null);
        }
    }
    
    

    编译结果1:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package study.lombok;
    
    import lombok.NonNull;
    
    public class NonNullAnnotation {
        public NonNullAnnotation() {
        }
    
        public void testPersonIsNull(@NonNull NonNullAnnotation.Person person) {
            if (person == null) {
                throw new NullPointerException("person is marked non-null but is null");
            } else {
                System.out.println(person.getName());
            }
        }
    
        public static void main(String[] args) {
            NonNullAnnotation nonNullAnnotation = new NonNullAnnotation();
            nonNullAnnotation.testPersonIsNull((NonNullAnnotation.Person)null);
        }
    
        public class Person {
            private String name;
            private int age;
    
            public Person() {
            }
    
            public String getName() {
                return this.name;
            }
    
            public int getAge() {
                return this.age;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public void setAge(int age) {
                this.age = age;
            }
        }
    }
    
    

    代码片段2:

    package study.lombok;
    
    import lombok.Data;
    import lombok.Getter;
    import lombok.NonNull;
    import lombok.Setter;
    
    /**
     * @Author LynHB
     * @Description : Lombok @NonNull注解测试
     * @Date 20:23 2020/6/24
     **/
    public class NonNullAnnotation {
    
        @Getter
        @Setter
        @Data
        public static class Person{
            @NonNull private String name;
            private int age;
        }
    
        public void testPersonIsNull(Person person){
            System.out.println(person.getName());
        }
    
        public static void  main(String[] args){
            NonNullAnnotation nonNullAnnotation = new NonNullAnnotation();
            Person person = new Person(null);
            nonNullAnnotation.testPersonIsNull(person);
        }
    }
    
    

    编译结果2:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package study.lombok;
    
    import lombok.NonNull;
    
    public class NonNullAnnotation {
        public NonNullAnnotation() {
        }
    
        public void testPersonIsNull(NonNullAnnotation.Person person) {
            System.out.println(person.getName());
        }
    
        public static void main(String[] args) {
            NonNullAnnotation nonNullAnnotation = new NonNullAnnotation();
            NonNullAnnotation.Person person = new NonNullAnnotation.Person((String)null);
            nonNullAnnotation.testPersonIsNull(person);
        }
    
        public static class Person {
            @NonNull
            private String name;
            private int age;
    
            @NonNull
            public String getName() {
                return this.name;
            }
    
            public int getAge() {
                return this.age;
            }
    
            public void setName(@NonNull String name) {
                if (name == null) {
                    throw new NullPointerException("name is marked non-null but is null");
                } else {
                    this.name = name;
                }
            }
    
            public void setAge(int age) {
                this.age = age;
            }
    
            public Person(@NonNull String name) {
                if (name == null) {
                    throw new NullPointerException("name is marked non-null but is null");
                } else {
                    this.name = name;
                }
            }
    
            public boolean equals(Object o) {
                if (o == this) {
                    return true;
                } else if (!(o instanceof NonNullAnnotation.Person)) {
                    return false;
                } else {
                    NonNullAnnotation.Person other = (NonNullAnnotation.Person)o;
                    if (!other.canEqual(this)) {
                        return false;
                    } else {
                        Object this$name = this.getName();
                        Object other$name = other.getName();
                        if (this$name == null) {
                            if (other$name == null) {
                                return this.getAge() == other.getAge();
                            }
                        } else if (this$name.equals(other$name)) {
                            return this.getAge() == other.getAge();
                        }
    
                        return false;
                    }
                }
            }
    
            protected boolean canEqual(Object other) {
                return other instanceof NonNullAnnotation.Person;
            }
    
            public int hashCode() {
                int PRIME = true;
                int result = 1;
                Object $name = this.getName();
                int result = result * 59 + ($name == null ? 43 : $name.hashCode());
                result = result * 59 + this.getAge();
                return result;
            }
    
            public String toString() {
                return "NonNullAnnotation.Person(name=" + this.getName() + ", age=" + this.getAge() + ")";
            }
        }
    }
    

    3.3.2 支持配置

    • lombok.nonNull.exceptionType =NullPointerException | IllegalArrumentException|JDK|Guava|Assertion(默认为:NullPointerException)
    • lombok.nonNull.flagUsage 同上

    3.4 @Cleanup

    3.4.1 示例

    代码片段:

    package study.lombok;
    
    import lombok.Cleanup;
    
    import java.io.*;
    
    /**
     * @Author LynHB
     * @Description :
     * @Date 21:03 2020/6/24
     **/
    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 == -1) break;
                out.write(b, 0, r);
            }
        }
    }
    
    

    编译结果:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package study.lombok;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Collections;
    
    public class CleanupExample {
        public CleanupExample() {
        }
    
        public static void main(String[] args) throws IOException {
            FileInputStream in = new FileInputStream(args[0]);
    
            try {
                FileOutputStream out = new FileOutputStream(args[1]);
    
                try {
                    byte[] b = new byte[10000];
    
                    while(true) {
                        int r = in.read(b);
                        if (r == -1) {
                            return;
                        }
    
                        out.write(b, 0, r);
                    }
                } finally {
                    if (Collections.singletonList(out).get(0) != null) {
                        out.close();
                    }
    
                }
            } finally {
                if (Collections.singletonList(in).get(0) != null) {
                    in.close();
                }
    
            }
        }
    }
    
    

    3.4.2 支持配置

    • lombok.cleanup.flagUsage 同上

    3.5 @Getter/@Setter

    3.5.1 示例

    • 通过Getter Setter注解进行生成getter和setter方法
    • 在注解里可以设置对应方法的访问级别(public、protected、package、private)
      代码片段:
    package study.lombok;
    
    import lombok.AccessLevel;
    import lombok.Getter;
    import lombok.Setter;
    
    /**
     * @Author LynHB
     * @Description : Getting Setting方法demo
     * @Date 22:48 2020/6/24
     **/
    public class GetterSetterExample {
        @Getter
        @Setter
        private int age = 10;
        @Setter(AccessLevel.PROTECTED) private String name;
    
        @Override public String toString() {
            return String.format("%s (age: %d)", name, age);
        }
    }
    
    

    编译结果:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package study.lombok;
    
    public class GetterSetterExample {
        private int age = 10;
        private String name;
    
        public GetterSetterExample() {
        }
    
        public String toString() {
            return String.format("%s (age: %d)", this.name, this.age);
        }
    
        public int getAge() {
            return this.age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        protected void setName(String name) {
            this.name = name;
        }
    }
    
    

    3.5.2 支持配置

    配置项 可选值 默认值 配置说明
    lombok.accessors.chain true false false 如果设置为true,会返回this(代替viod)。显式的配置@Accessors注解chain会优先于此设置。
    lombok.accessors.fluent true false false 如果设置为true,不会生成'get' 'is' 'set'前缀,相反的是方法会用自身的字段名称作为函数名。显式的配置@Accessors注解fluent会优先于此设置。
    lombok.accessors.prefix +=自定义前缀字符串 空列表 这是一个列表属性;可以通过+=进行添加。继承父配置文件中的删除-=操作。Lombok将从字段名称中删除任何匹配的字段前缀,以便确定要生成的getter/setter的名称。例如,如果m是这个设置中列出的前缀之一,那么一个名为mFoobar的字段将导致一个名为getFoobar()的getter,而不是getMFoobar()。显式的配置@Accessors注解prefix会优先于此设置。
    lombok.getter.noIsPrefix true false false 如果设置为true,为boolean类型设置get前缀而非is前缀,所有生成的代码有调用到getters的地方,比如@ToString也会用get而不是is。
    lombok.setter.flagUsage warning error 不设置 同其他注解
    lombok.getter.flagUsage warning eroor 不设置 同其他注解
    lombok.copyableAnnotations 完全限定类型列表 空集合 lombok将会拷贝这些注解从字段复制到setter参数和getter方法。注意lombok附带了一些开箱的注解,这些注解都可以复制,所有流行的可空/非空注解。

    3.6 @ToString

    3.6.1 示例

    代码片段:

    package study.lombok;
    
    import lombok.ToString;
    
    import java.awt.*;
    
    /**
     * @Author LynHB
     * @Description : ToString注解测试
     * @Date 13:26 2020/6/25
     **/
    @ToString
    public class ToStringExample {
        private static final int STATIC_VAR = 10;
        private String name;
        private Shape shape = new Square(5, 10);
        private String[] tags;
        @ToString.Exclude private int id;
    
        public String getName() {
            return this.name;
        }
    
        public static class Shape{
    
        }
    
        @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;
            }
        }
    }
    
    

    编译结果:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package study.lombok;
    
    import java.util.Arrays;
    
    public class ToStringExample {
        private static final int STATIC_VAR = 10;
        private String name;
        private ToStringExample.Shape shape = new ToStringExample.Square(5, 10);
        private String[] tags;
        private int id;
    
        public ToStringExample() {
        }
    
        public String getName() {
            return this.name;
        }
    
        public String toString() {
            return "ToStringExample(name=" + this.getName() + ", shape=" + this.shape + ", tags=" + Arrays.deepToString(this.tags) + ")";
        }
    
        public static class Square extends ToStringExample.Shape {
            private final int width;
            private final int height;
    
            public Square(int width, int height) {
                this.width = width;
                this.height = height;
            }
    
            public String toString() {
                return "ToStringExample.Square(super=" + super.toString() + ", width=" + this.width + ", height=" + this.height + ")";
            }
        }
    
        public static class Shape {
            public Shape() {
            }
        }
    }
    
    

    3.6.2 支持配置

    配置项 可选值 默认值 配置说明
    lombok.toString.includeFieldNames true false true 通常,lombok以fieldName = fieldValue的形式为每个字段生成toString响应的片段。如果设置成false,lombok将会省略名称字段,只部署一个逗号分隔的所有字段值列表。注解参数“includeFieldNames”,如果明确的指定,优先于此配置。
    lombok.toString.doNotUseGetters true false false 如果设置成true,lombok将会直接访问字段,跳过getters当生产生产toString方法时。这个注解参数“doNotUseGetters”,如果明确指定,则优先于此配置
    lombok.toString.callSuper call skip warn skip 如果设置成call,lombok将会调用父类实现的toString当你的类继承父类时。如果设置成skip,不会这调用。如果设置成warn,也没有生成这样的调用,但是lombok会生成一个警告来告诉你。
    lombok.toString.flagUsage warning error 不设置 同其他注解

    3.7 @EqualsAndHashCode

    3.7.1 示例

    3.7.2 支持配置

    配置项 可选值 默认值 配置说明

    3.8 @NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor

    3.8.1 示例

    3.8.2 支持配置

    配置项 可选值 默认值 配置说明

    3.9 @Data

    3.9.1 示例

    3.9.2 支持配置

    配置项 可选值 默认值 配置说明

    3.10 @Value

    3.10.1 示例

    3.10.2 支持配置

    配置项 可选值 默认值 配置说明

    3.11 @Builder

    3.11.1 示例

    3.11.2 支持配置

    配置项 可选值 默认值 配置说明

    3.12 @SneakyThrows

    3.12.1 示例

    3.12.2 支持配置

    配置项 可选值 默认值 配置说明

    3.13 @Getter(lazy=true)

    3.13.1 示例

    3.13.2 支持配置

    配置项 可选值 默认值 配置说明

    3.14 @Log

    你可以使用变量@Log在你的class中(保证对应的logging是你有用的,说白了就是你的依赖中要有它);之前的做法是你需要定义一个static final log的字段,初始化它各种巴拉巴拉的语句,现在只需要对应的@Log注解即可实现:

    @CommonsLog
    // 被翻译成如下
    private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
    @Flogger
    // 被翻译成如下
    private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass();
    @JBossLog
    // 被翻译成如下
    private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
    @Log
    // 被翻译成如下
    private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
    @Log4j
    // 被翻译成如下
    private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
    @Log4j2
    // 被翻译成如下
    private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
    @Slf4j
    // 被翻译成如下
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
    @XSlf4j
    // 被翻译成如下
    private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
    @CustomLog
    // 被翻译成如下
    private static final com.foo.your.Logger log = com.foo.your.LoggerFactory.createYourLogger(LogExample.class);
    

    3.14.1 示例

    package study.dynamic.proxy.entity;
    
    
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @Author LynHB
     * @Description :
     *      Baby 实现来自IPerson接口的类
     * @Date 23:17 2020/7/8
     **/
    @Slf4j
    public class Baby implements IPerson {
        @Override
        public void eat(String dishName) {
            log.info("mother feed me {}",dishName);
        }
    
        @Override
        public void hungry() {
            log.info("wa wa wa");
        }
    }
    

    3.14.2 支持配置

    配置项 可选值 默认值 配置说明

    相关文章

      网友评论

          本文标题:Lombok基础使用

          本文链接:https://www.haomeiwen.com/subject/cjtaxktx.html