Lombok之使用详解

前言

  在Java中,封装是一个非常好的机制,最常见的封装莫过于get,set方法了,无论是Intellij idea 还是Eclipse,都提供了快速生成get,set方法的快捷键,使用起来很是方便,其实,我们还有更方便的办法,那就是-Lombok:非常强大的POJO注解器。

Lombok是什么?

  lombok 提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码。特别是相对于 POJO。

如何安装Lombok?

  使用 lombok 是需要安装的,如果不安装,IDE 则无法解析 lombok 注解。先在官网下载最新版本的 JAR 包

  1. 双击下载下来的 JAR 包安装 lombok;
    我选择这种方式安装的时候提示没有发现任何 IDE,所以我没安装成功,我是手动安装的。
  2. eclipse / myeclipse 手动安装 lombok(Mac 下eclipse安装Lombok插件
    1. 将 lombok.jar 复制到 myeclipse.ini / eclipse.ini 所在的文件夹目录下
    2. 打开 eclipse.ini / myeclipse.ini,在最后面插入以下两行并保存: 

      -Xbootclasspath/a:lombok.jar
      -javaagent:lombok.jar
    3. 重启 eclipse / myeclipse

Lombok使用详解

  • 添加POM依赖:

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.0</version>
    </dependency>
  • Lombok提供注解方式来提高代码的简洁性,常用注解概览:

    • @Data:注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法,相当于同时加上以下注解@Setter @Getter,@ToString,@EqualsAndHashCode
    • @Setter、@Getter:注解在类和属性上;为属性提供 setting、getting 方法
    • @ToString:生成toString方法,默认情况下,会输出类名、所有属性,属性按照顺序输出,以逗号分割。
    • @EqualsAndHashCode:实现equals()方法和hashCode()方法
    • @Builder:构建 建造者模式
    • @NonNull:该注解快速判断是否为空,如果为空,则抛出java.lang.NullPointerException
    • @Synchronized:该注解自动添加到同步机制,有趣的是,生成的代码并不是直接锁方法,而是锁代码块, 作用范围是方法上
    • @Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象
    • @NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
    • @RequiredArgsConstructor:注解在类上;为类提供一个部分参的构造方法
    • @AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
    • @Cleanup:用于确保已分配的资源被释放,如IO的连接关闭
    • @SneakyThrows:抛异常
    • @Accessors(chain = true):使用链式结构

@Data

  注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法,相当于同时加上以下注解@Setter @Getter,@ToString,@EqualsAndHashCode

1 @Data
2 public class Person {
3     private String name;
4     private String address;
5     private String city;
6     private String state;
7     private String zip;
8     private Date brithday;
9 }

效果如下:

@[email protected]

  注解在类和属性上;为属性提供 setting、getting 方法

public class Person {
    @[email protected]
    private String name;
}

  等价源码:

1 public String getName() {
2         return name;
3     }
4
5 public void setName(String name) {
6         this.name = name;
7 }

@ToString

生成toString方法,默认情况下,会输出类名、所有属性,属性按照顺序输出,以逗号分割。但需要注意的是:@ToString有多个属性可以进一步设置:

    • callSuper 是否输出父类的toString方法,默认为false
    • includeFieldNames 是否包含字段名称,默认为true
    • exclude 排除生成tostring的字段

      使用方法:

      1 @ToString(callSuper = true,exclude ={"name"})
      2 public class Person {
      3     private String name;
      4     private String address;
      5 }

      等价源码:

      1 public String toString() {
      2  return "Person{" +
      3                 "address=‘" + address + ‘\‘‘ +
      4     ‘}‘;
      5 }

@NonNull

该注解快速判断是否为空,如果为空,则抛出java.lang.NullPointerException
  使用方法

1 public class Person {
2
3     private String name;
4
5     @[email protected]@NonNull
6     private List<Person> member;
7 }

  等价源码:

 1 @NonNull
 2 private List<Person> members;
 3
 4 public Family(@NonNull final List<Person> members) {
 5     if (members == null) throw new java.lang.NullPointerException("members");
 6     this.members = members;
 7 }
 8
 9 @NonNull
10 public List<Person> getMembers() {
11     return members;
12 }
13
14 public void setMembers(@NonNull final List<Person> members) {
15     if (members == null) throw new java.lang.NullPointerException("members");
16     this.members = members;
17 }

@Synchronized

该注解自动添加到同步机制,有趣的是,生成的代码并不是直接锁方法,而是锁代码块, 作用范围是方法上。
使用方法:

1 private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");
2
3 @Synchronized
4 public String synchronizedFormat(Date date) {
5     return format.format(date);
6 }

等价源码:

1 private final java.lang.Object $lock = new java.lang.Object[0];
2 private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");
3
4 public String synchronizedFormat(Date date) {
5     synchronized ($lock) {
6         return format.format(date);
7     }
8 }

@Cleanup

注释可用于确保已分配的资源被释放,如IO的连接关闭。
使用方法:

1 public void testCleanUp() {
2     try {
3         @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
4         baos.write(new byte[] {‘Y‘,‘e‘,‘s‘});
5         System.out.println(baos.toString());
6     } catch (IOException e) {
7         e.printStackTrace();
8     }
9 }

等价源码:

 1 public void testCleanUp() {
 2     try {
 3         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 4         try {
 5             baos.write(new byte[]{‘Y‘, ‘e‘, ‘s‘});
 6             System.out.println(baos.toString());
 7         } finally {
 8             baos.close();
 9         }
10     } catch (IOException e) {
11         e.printStackTrace();
12     }
13 }

@Accessors(chain = true)

  使用链式结构

  • 使用方法:

     1 public class Student {
     2         private String name;
     3         private int age;
     4
     5         public String getName() {
     6             return name;
     7         }
     8
     9         public Student setName(String name) {
    10             this.name = name;
    11             return this;
    12         }
    13
    14         public int getAge() {
    15             return age;
    16         }
    17
    18         public Student setAge(int age) {
    19             return this;
    20         }
    21     }
  • 等价源码:

    1 @Accessors(chain = true)
    2     @Data
    3     @NoArgsConstructor(staticName = "of")
    4     public class Student {
    5         private String name;
    6         private int age;
    7     }
  • 调用

    1 Student student = Student.of().setName("wsk").setAge(12);

@Builder

  使用builder,构建 建造者模式

  • 例一:

    • 使用@Builder

      1 @Builder
      2     public class Student {
      3         private String name;
      4         private int age;
      5     }
    • 调用示例:

      1 Student student = Student.builder().name("zs").age(24).build();
    • 等价源码:

       1 public class Student {
       2         private String name;
       3         private int age;
       4
       5         public String getName() {
       6                 return name;
       7         }
       8
       9         public void setName(String name) {
      10                 this.name = name;
      11         }
      12
      13         public int getAge() {
      14                 return age;
      15         }
      16
      17         public void setAge(int age) {
      18                 this.age = age;
      19         }
      20
      21         public static Builder builder(){
      22                 return new Builder();
      23         }
      24         public static class Builder{
      25                 private String name;
      26                 private int age;
      27                 public Builder name(String name){
      28                         this.name = name;
      29                         return this;
      30                 }
      31
      32                 public Builder age(int age){
      33                         this.age = age;
      34                         return this;
      35                 }
      36
      37                 public Student build(){
      38                         Student student = new Student();
      39                         student.setAge(age);
      40                         student.setName(name);
      41                         return student;
      42                 }
      43         }
      44     }
  • 例二:利用builder模式设计的Java类  
    • 如果能将创建JavaBean和设置内容揉在一起,在传入builder中的参数不合乎业务或者非法,那么就不能创建student对象,这时候可以通过捕获IllegalArgumentException,从而得知失败的原因;
    • 引入Builder设计模式以后,代码保持JavaBean好的可读性,但同时增强了安全性,将Student类的创建和设置内容揉在了一起,并增加了安全性检查,提高了系统的健壮性,同时防止了编码中的一些疏忽。
    • Java示例:

       1 public class Student {
       2     private String id;
       3     private String name;
       4     private String sex;
       5     private int age;
       6     private String department;
       7
       8     public static class Builder {
       9         /*
      10          * 只能指定一次。
      11          */
      12         private final String id;
      13         private final String department;
      14
      15         private String name = "";
      16         private String sex = "男";
      17         private int age = 20;
      18
      19         /*
      20          * 非空属性,必须在构造器中指定。
      21          */
      22         public Builder(String id, String department) {
      23             this.id = id;
      24             this.department = department;
      25         }
      26
      27         /*
      28          * name,sex,age可选择属性,提供特殊的setter方法。
      29          */
      30         public Builder name(String name) {
      31             this.name = name;
      32             return this;
      33         }
      34
      35         public Builder sex(String sex) {
      36             this.sex = sex;
      37             return this;
      38         }
      39
      40         public Builder age(int age) {
      41             this.age = age;
      42             return this;
      43         }
      44
      45         /*
      46          * Student对象创建器,想得到一个Student对象必须使用build 方法,
      47          * 在方法中增加对Builder参数的验证,并以异常的形式告诉给开发人员。
      48          */
      49         public Student build() {
      50             /* 检查Builder对象中的数据是否合法。
      51              * 针对这个例子,就是检查主键冲突,外键制约等
      52              * 如果不满足我们可以抛出一个IllegalArgumentException
      53              */
      54             return new Student(this);
      55
      56         }
      57
      58     }
      59
      60     private Student(Builder builder) {
      61         this.id = builder.id;
      62         this.name = builder.name;
      63         this.sex = builder.sex;
      64         this.age = builder.age;
      65         this.department = builder.department;
      66     }
      67
      68     /*
      69      * 只提供getter方法
      70      */
      71     public String getId() {
      72         return id;
      73     }
      74
      75     public String getName() {
      76         return name;
      77     }
      78
      79     public String getSex() {
      80         return sex;
      81     }
      82
      83     public int getAge() {
      84         return age;
      85     }
      86
      87     public String getDepartment() {
      88         return department;
      89     }
      90
      91 }
    • 创建对象一:

      1      student = new Student.Builder("03041013", "计算机").name("李华").build();
    • 创建对象二:

      1     Student.Builder builder = new Student.Builder("03041013", "计算机");
      2     builder.name("李华");
      3     Student student = builder.build();

小结:

  • 很明显,使用 lombok 要简洁许多,特别是在类的属性较多的情况下;
  • 同时也避免了修改字段名字时候忘记修改方法名所犯的低级错误;

参考资料

原文地址:https://www.cnblogs.com/cb0327/p/10040671.html

时间: 2024-11-09 22:31:55

Lombok之使用详解的相关文章

Intellij IDEA 安装 lombok及使用详解

在项目开发中会经常使用到bean,entity等类,绝大部分数据类中都需要get.set.toString.equals和hashCode方法,虽然eclipse和idea开发环境下都有自动生成的快捷方式.但自动生成这些代码后,一方面整体的代码量变大了,另一方面如果实体中的属性一旦有修改.删除或增加时,需要重新生成或删除get/set等方法,给代码维护增加负担. 而使用了lombok则不一样,使用了lombok的注解(@Setter,@Getter,@ToString,@@RequiredArg

Intellij IDEA 安装lombok及使用详解

项目中经常使用bean,entity等类,绝大部分数据类类中都需要get.set.toString.equals和hashCode方法,虽然eclipse和idea开发环境下都有自动生成的快捷方式,但自动生成这些代码后,如果bean中的属性一旦有修改.删除或增加时,需要重新生成或删除get/set等方法,给代码维护增加负担.而使用了lombok则不一样,使用了lombok的注解(@Setter,@Getter,@ToString,@@RequiredArgsConstructor,@Equals

SpringBoot与PageHelper的整合示例详解

SpringBoot与PageHelper的整合示例详解 1.PageHelper简介 PageHelper官网地址: https://pagehelper.github.io/ 摘要: com.github.pagehelper.PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件. PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件,其实我并不想加上好用两个字,但是为了表扬插件作者开源免费的崇高精神,我毫不犹豫的加上了好用一词作为赞美. 原本以为

SpringBoot注解最全详解

一.注解(annotations)列表 @SpringBootApplication:包含了@ComponentScan.@Configuration和@EnableAutoConfiguration注解.其中@ComponentScan让spring Boot扫描到Configuration类并把它加入到程序上下文. @Configuration 等同于spring的XML配置文件:使用Java代码可以检查类型安全. @EnableAutoConfiguration 自动配置. @Compon

Spring Boot2 系列教程 (五) | yaml 配置文件详解

自定义属性加载 首先构建 SpringBoot 项目,不会的看这篇旧文 使用 IDEA 构建 Spring Boot 工程. 首先在项目根目录 src >> resource >>?application.properties 文件下加入以下自定义属性: # 防止读取乱码 spring.http.encoding.charset=UTF-8 # 项目启动端口 server.port=9999 # 自定义配置 com.nasus.author.name=一个优秀的废人 com.nas

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

转载:DenseNet算法详解

原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/article/details/53468483 本文这里仅当学习笔记使用,具体细节建议前往原文细度. 论文:Densely Connected Convolutional Networks 论文链接:https://arxiv.org/pdf/1608.06993.pdf 代码的github链接:h

MariaDB(MySQL)创建、删除、选择及数据类型使用详解

一.MariaDB简介(MySQL简介略过) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品.在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB. MariaDB由MySQL的创始人Michael Widenius(英语:Michael Widenius)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL A

HttpServletResponse和HttpServletRequest详解

HttpServletResponse,HttpServletRequest详解 1.相关的接口 HttpServletRequest HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及IP地址,还可以获取客户端正在使用的通信协议等信息.下表是接口HttpServletRequest的常用方法. 说明:HttpServ