zoukankan      html  css  js  c++  java
  • Lombok 天宇轩

    Lombok 简介

    Lombok 是一种 Java 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO)。它通过注释实现这一目的。通过在开发环境中实现 Lombok,开发人员可以节省构建诸如 hashCode()equals()getter / setter 这样的方法以及以往用来分类各种 accessor 和 mutator 的大量时间。

    Lombok 安装

    使 IntelliJ IDEA 支持 Lombok 方式如下:

    • Intellij 设置支持注解处理

      点击 File > Settings > Build > Annotation Processors

      勾选 Enable annotation processing

    • 安装插件

      点击 Settings > Plugins > Browse repositories

      查找 Lombok Plugin 并进行安装

      重启 IntelliJ IDEA

    • 将 lombok 添加到 pom 文件

     <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.6</version>
                <scope>provided</scope>
            </dependency>
    

      

    Lombok 使用

    官网API

    Lombok 提供注解API 来修饰指定的类:

    @Getter and @Setter

    @Getter and @Setter Lombok 代码:
    
    @Getter @Setter 
    private boolean employed = true;
    @Setter(AccessLevel.PROTECTED) 
    private String name;
    等价于 Java 源码:
    
    private boolean employed = true;
    private String name;
    ​
    public boolean isEmployed() {
        return employed;
    }
    ​
    public void setEmployed(final boolean employed) {
        this.employed = employed;
    }
    ​
    protected void setName(final String name) {
        this.name = name;
    }
    

      

    @NonNull

    @NonNull Lombok 代码:
    
    @Getter @Setter @NonNull
    private List<Person> members;
    等价于 Java 源码:
    
    @NonNull
    private List<Person> members;
    ​
    public Family(@NonNull final List<Person> members) {
        if (members == null) throw new java.lang.NullPointerException("members");
        this.members = members;
    }
        
    @NonNull
    public List<Person> getMembers() {
        return members;
    }
    ​
    public void setMembers(@NonNull final List<Person> members) {
        if (members == null) throw new java.lang.NullPointerException("members");
        this.members = members;
    }
    

      

    @ToString

    @ToString Lombok 代码:
    
    @ToString(callSuper=true,exclude="someExcludedField")
    public class Foo extends Bar {
        private boolean someBoolean = true;
        private String someStringField;
        private float someExcludedField;
    }
    等价于 Java 源码:
    
    public class Foo extends Bar {
        private boolean someBoolean = true;
        private String someStringField;
        private float someExcludedField;
        
        @java.lang.Override
        public java.lang.String toString() {
            return "Foo(super=" + super.toString() +
                ", someBoolean=" + someBoolean +
                ", someStringField=" + someStringField + ")";
        }
    }
    

      

    @EqualsAndHashCode

    @EqualsAndHashCode Lombok 代码:
    
    @EqualsAndHashCode(callSuper=true,exclude={"address","city","state","zip"})
    public class Person extends SentientBeing {
        enum Gender { Male, Female }
    ​
        @NonNull private String name;
        @NonNull private Gender gender;
        
        private String ssn;
        private String address;
        private String city;
        private String state;
        private String zip;
    }
    等价于 Java 源码:
    
    public class Person extends SentientBeing {
        
        enum Gender {
            /*public static final*/ Male /* = new Gender() */,
            /*public static final*/ Female /* = new Gender() */;
        }
        @NonNull
        private String name;
        @NonNull
        private Gender gender;
        private String ssn;
        private String address;
        private String city;
        private String state;
        private String zip;
        
        @java.lang.Override
        public boolean equals(final java.lang.Object o) {
            if (o == this) return true;
            if (o == null) return false;
            if (o.getClass() != this.getClass()) return false;
            if (!super.equals(o)) return false;
            final Person other = (Person)o;
            if (this.name == null ? other.name != null : !this.name.equals(other.name)) return false;
            if (this.gender == null ? other.gender != null : !this.gender.equals(other.gender)) return false;
            if (this.ssn == null ? other.ssn != null : !this.ssn.equals(other.ssn)) return false;
            return true;
        }
        
        @java.lang.Override
        public int hashCode() {
            final int PRIME = 31;
            int result = 1;
            result = result * PRIME + super.hashCode();
            result = result * PRIME + (this.name == null ? 0 : this.name.hashCode());
            result = result * PRIME + (this.gender == null ? 0 : this.gender.hashCode());
            result = result * PRIME + (this.ssn == null ? 0 : this.ssn.hashCode());
            return result;
        }
    }

    @Data

    @Data Lombok 代码:
    
    @Data(staticConstructor="of")
    public class Company {
        private final Person founder;
        private String name;
        private List<Person> employees;
    }
    等价于 Java 源码:
    
    public class Company {
        private final Person founder;
        private String name;
        private List<Person> employees;
        
        private Company(final Person founder) {
            this.founder = founder;
        }
        
        public static Company of(final Person founder) {
            return new Company(founder);
        }
        
        public Person getFounder() {
            return founder;
        }
        
        public String getName() {
            return name;
        }
        
        public void setName(final String name) {
            this.name = name;
        }
        
        public List<Person> getEmployees() {
            return employees;
        }
        
        public void setEmployees(final List<Person> employees) {
            this.employees = employees;
        }
        
        @java.lang.Override
        public boolean equals(final java.lang.Object o) {
            if (o == this) return true;
            if (o == null) return false;
            if (o.getClass() != this.getClass()) return false;
            final Company other = (Company)o;
            if (this.founder == null ? other.founder != null : !this.founder.equals(other.founder)) return false;
            if (this.name == null ? other.name != null : !this.name.equals(other.name)) return false;
            if (this.employees == null ? other.employees != null : !this.employees.equals(other.employees)) return false;
            return true;
        }
        
        @java.lang.Override
        public int hashCode() {
            final int PRIME = 31;
            int result = 1;
            result = result * PRIME + (this.founder == null ? 0 : this.founder.hashCode());
            result = result * PRIME + (this.name == null ? 0 : this.name.hashCode());
            result = result * PRIME + (this.employees == null ? 0 : this.employees.hashCode());
            return result;
        }
        
        @java.lang.Override
        public java.lang.String toString() {
            return "Company(founder=" + founder + ", name=" + name + ", employees=" + employees + ")";
        }
    }
    所有属性的get和set方法
    toString 方法
    hashCode方法
    equals方法
    

      

    @Cleanup

    @Cleanup Lombok 代码:
    
    public void testCleanUp() {
        try {
            @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
            baos.write(new byte[] {'Y','e','s'});
            System.out.println(baos.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    等价于 Java 源码:
    
    public void testCleanUp() {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try {
                baos.write(new byte[]{'Y', 'e', 's'});
                System.out.println(baos.toString());
            } finally {
                baos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

      

    @Synchronized

    @Synchronized Lombok 代码:
    
    private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");
    ​
    @Synchronized
    public String synchronizedFormat(Date date) {
        return format.format(date);
    }
    等价于 Java 源码:
    
    private final java.lang.Object $lock = new java.lang.Object[0];
    private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");
    ​
    public String synchronizedFormat(Date date) {
        synchronized ($lock) {
            return format.format(date);
        }
    }
    

      

    @SneakyThrows

    @SneakyThrows Lombok 代码:
    
    @SneakyThrows
    public void testSneakyThrows() {
        throw new IllegalAccessException();
    }
    Exception in thread "main" java.lang.IllegalAccessException
        at com.topcheer.springboot01.Test.main(Test.java:15)
    等价于 Java 源码:
    
    public void testSneakyThrows() {
        try {
            throw new IllegalAccessException();
        } catch (java.lang.Throwable $ex) {
            throw lombok.Lombok.sneakyThrow($ex);
        }
    }
    java.lang.IllegalAccessException
        at com.topcheer.springboot01.Test.main(Test.java:13)
    示例
    使用 Lombok 定义一个 Java Bean
    
    import lombok.Data;
    import lombok.ToString;
    ​
    @Data
    @ToString(exclude = "age")
    public class Person {
        private String name;
        private Integer age;
        private String sex;
    }
    测试
    
    Person person = new Person();
    person.setName("张三");
    person.setAge(20);
    person.setSex("男");
    System.out.println(person.toString());
    // output: Person(name=张三, sex=男)
    

      

    其他说明

    @AllArgsConstructor
    这个注解是所有的参数构造器
    @NoArgsConstructor
    无参构造
    @RequiredArgsConstructor
    为每个需要特殊处理的字段生成一个带有1个参数的构造函数,且生成的构造为私有,需要通过设置 staticName 来获取访问;
    @RequiredArgsConstructor
    功能
    ​
    生成一个包含必填参数的构造函数
    ​
    注意
    ​
    要与@NonNull 搭配使用,该注解修饰的属性就是必填参数
    ​
    源码
    ​
    @RequiredArgsConstructor
    public class LombokDemo {
    ​
      @NonNull private Integer id;
      private String name;
    }
    ​
    编译后
    ​
    package xyz.mrwood.study.lombok;
    ​
    import java.beans.ConstructorProperties;
    import lombok.NonNull;
    ​
    public class LombokDemo {
      @NonNull
      private Integer id;
      private String name;
    ​
      @ConstructorProperties({"id"})
      public LombokDemo(@NonNull Integer id) {
          if(id == null) {
              throw new NullPointerException("id");
          } else {
              this.id = id;
          }
      }
    }
     
    
    @NoAragsConstructor
    功能
    ​
    添加一个无参构造函数
    ​
    注意
    ​
    这个注解在没有其它有参构造函数的情况下使用意义不大,因为在这种情况下java默认会添加一个无参构造函数
    ​
    源码
    ​
    @NoArgsConstructor
    public class LombokDemo {
    ​
      private Integer id;
      private String name;
    }
    ​
    编译后
    ​
    package xyz.mrwood.study.lombok;
    ​
    public class LombokDemo {
      private Integer id;
      private String name;
    ​
      public LombokDemo() {
      }
    }
    ​
    ​
    @AllArgsConstructor
    功能
    ​
    添加一个所有参数的构造函数
    ​
    源码
    ​
    @AllArgsConstructor
    public class LombokDemo {
    ​
      private Integer id;
      private String name;
    }
    编译后
    ​
    package xyz.mrwood.study.lombok;
    ​
    import java.beans.ConstructorProperties;
    ​
    public class LombokDemo {
      private Integer id;
      private String name;
    ​
      @ConstructorProperties({"id", "name"})
      public LombokDemo(Integer id, String name) {
          this.id = id;
          this.name = name;
      }
    }
    

      

    @Value

    @Value
    功能
    ​
    不可变类的@Date, 他会默认给属性加上final
    ​
    源码
    ​
    @Value
    public class LombokDemo {
    ​
      private Integer id;
      private String name;
    }
    ​
    编译后
    ​
    package xyz.mrwood.study.lombok;
    ​
    import java.beans.ConstructorProperties;
    ​
    public final class LombokDemo {
      private final Integer id;
      private final String name;
    ​
      @ConstructorProperties({"id", "name"})
      public LombokDemo(Integer id, String name) {
          this.id = id;
          this.name = name;
      }
    ​
      public Integer getId() {
          return this.id;
      }
    ​
      public String getName() {
          return this.name;
      }
    ​
      public boolean equals(Object o) {
          if(o == this) {
              return true;
          } else if(!(o instanceof LombokDemo)) {
              return false;
          } else {
              LombokDemo other = (LombokDemo)o;
              Integer this$id = this.getId();
              Integer other$id = other.getId();
              if(this$id == null) {
                  if(other$id != null) {
                      return false;
                  }
              } else if(!this$id.equals(other$id)) {
                  return false;
              }
    ​
              String this$name = this.getName();
              String other$name = other.getName();
              if(this$name == null) {
                  if(other$name != null) {
                      return false;
                  }
              } else if(!this$name.equals(other$name)) {
                  return false;
              }
    ​
              return true;
          }
      }
    ​
      public int hashCode() {
          boolean PRIME = true;
          byte result = 1;
          Integer $id = this.getId();
          int result1 = result * 59 + ($id == null?43:$id.hashCode());
          String $name = this.getName();
          result1 = result1 * 59 + ($name == null?43:$name.hashCode());
          return result1;
      }
    ​
      public String toString() {
          return "LombokDemo(id=" + this.getId() + ", name=" + this.getName() + ")";
      }
    }
    

     

    @Builder

    注解提供了一种比较推崇的构建值对象的方式
    
    Dog dog = Dog.builder().age(12).name("大黄").build();
    System.out.println(dog);
    //Dog(name=大黄, age=12)
    但是的确很有创意,这些注解已经在jar中提供,只不过它是归在”lombok.experimental.” 包中;而基本功能在”lombok.” 包中。
    
    @Builder.Default
        private  Boolean flag = false;
    //Dog(name=大黄, age=12, flag=false) 初始化的时候会把值带进去,适合有默认值的

    @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前缀。
    

      

     

    @val @var

    使用Lombok ,java也能够像javascript一样使用弱类型定义变量了
    
    val注解变量申明是final类型 var注解变量是非final类型
    
     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());  
        }  
      }  
    }
    

      

     

    @UtilityClass

    功能
    
    把普通类转为工具类
    
    源码
    
      @UtilityClass
      public class LombokDemo {
    
          private Integer id = 1;
          private String name = "kiwi";
    
          public void util(){
    
              System.out.println("xxx");
          }
      }
    
    编译后
    
    package xyz.mrwood.study.lombok;
    
    public final class LombokDemo {
      private static Integer id = Integer.valueOf(1);
      private static String name = "kiwi";
    
      public static void util() {
          System.out.println("xxx");
      }
    
      private LombokDemo() {
          throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
      }
    }
    

      

    资料

    Lombok 官网 | Lombok Github

    IntelliJ IDEA - Lombok Plugin

  • 相关阅读:
    hihocoder1062 最近公共祖先·一
    POJ2342 Anniversary party(动态规划)(树形DP)
    【动态规划】抄近路(水题)
    【动态规划】数的划分 (动态规划)
    【动态规划】矩形嵌套 (DGA上的动态规划)
    hihocoder Popular Products(STL)
    hihocoder Counting Islands II(并查集)
    51nod 编辑距离问题(动态规划)
    51nod 最长公共子序列问题(动态规划)(LCS)(递归)
    目标提取——背景均匀、目标与背景相似
  • 原文地址:https://www.cnblogs.com/dalianpai/p/11656094.html
Copyright © 2011-2022 走看看