文章目录

  • pom.xml添加lombok
    • @Getter @Setter注解
    • @NonNull注解
    • @ToString
    • EqualsAndHashCode注解
    • @Data注解
    • @Cleanup注解
    • @NoArgsConstructor注解
    • @RequiredArgsConstructor注解
    • @AllArgsConstructor注解
    • @Value注解
    • @SneakyThrows注解
    • @Synchronized注解
    • @Builder注解
    • @SuperBuilder

在开发过程中,通常都会定义大量的JavaBean,然后通过IDE去产生其属性的构造器、getter、setter、equals、hashcode、toString方法,当要增加属性或者对某个属性进行改变时,比如命名、类型等,都需要重新去产生上面提到的这些方法。这样重复的劳动没有任何意义,Lombok里面的注解可以轻松解决这些问题。

  • 官方地址:https://projectlombok.org/
  • github地址:https://github.com/rzwitserloot/lombok

lombok实现的原理:主要是通过抽象语法树(AST),在编译处理后,对应到有其注解的类,那么注解编译器就会自动去对应项目中的注解对应到在lombok语法树中的注解文件,并经过自动编译对应来产生对应类中的getter或者setter方法,达到简化代码的目的

pom.xml添加lombok

org.projectlomboklomboktrue

@Getter @Setter注解

这一对注解从名字上就很好理解,用在成员变量前面,相当于为成员变量生成对应的get和set方法,同时还可以为生成的方法指定访问修饰符,当然,默认为public,直接来看下面的简单的例子:

// Rumenz.java
/*** @className: Rumenz* @description: TODO 类描述* @author: 入门小站 rumenz.com* @date: 2021/12/9**/
public class RumenzGetSet {@Getter @Setterprivate Integer id;@Getter @Setterprivate String name;}
  • 等价于
public class RumenzGetSet {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
@RestController
@RequestMapping("/rumenz")
public class RumenzController {@GetMapping("/index")public String index(){RumenzGetSet r=new RumenzGetSet();r.setId(1);r.setName("入门小站");return r.getId()+r.getName();}
}

访问http://127.0.0.1:8080/rumenz/index返回1入门小站

@NonNull注解

这个注解可以用在成员方法或者构造方法的参数前面,会自动产生一个关于此参数的非空检查,如果参数为空,则抛出一个空指针异常,举个例子来看看

public class RumenzNonNull {@Getter @Setter @NonNullprivate Integer id;@Getter @Setter @NonNullprivate String name;
}
  • 等价于
public class RumenzNonNull {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {if (id == null) throw new java.lang.NullPointerException("id");this.id = id;}public String getName() {return name;}public void setName(String name) {if (name == null) throw new java.lang.NullPointerException("name");this.name = name;}
}
@GetMapping("/index1")
public String index1(){RumenzNonNull r=new RumenzNonNull();r.setId(1);r.setName(null);return r.getId()+r.getName();
}

访问http://127.0.0.1:8080/rumenz/index1报错java.lang.NullPointerException: name is marked non-null but is null

@ToString

@ToString
public class RumenzToString {@Getter @Setterprivate Integer id;@Getter @Setterprivate String name;@Overridepublic String toString() {return "RumenzToString{" +"id=" + id +", name='" + name + '\'' +'}';}
}
  • 等价于
public class RumenzToString {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "RumenzToString{" +"id=" + id +", name='" + name + '\'' +'}';}
}
@GetMapping("/index2")
public String index2(){RumenzToString r=new RumenzToString();r.setId(1);r.setName("入门小站");return r.toString();
}

访问http://127.0.0.1:8080/rumenz/index1返回RumenzToString{id=1, name='入门小站'}

EqualsAndHashCode注解

@EqualsAndHashCode
public class RumenzEqualsAndHashCode {@Getter @Setterprivate Integer id;@Getter @Setterprivate String name;}
  • 等价于
public class RumenzEqualsAndHashCode {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof RumenzEqualsAndHashCode)) return false;RumenzEqualsAndHashCode that = (RumenzEqualsAndHashCode) o;return id.equals(that.id) &&name.equals(that.name);}}
@GetMapping("/index3")
public String index3(){RumenzEqualsAndHashCode r1=new RumenzEqualsAndHashCode();r1.setId(1);r1.setName("入门小站");RumenzEqualsAndHashCode r2=new RumenzEqualsAndHashCode();r2.setId(1);r2.setName("入门小站");if(r1.equals(r2)){return "相等";}return "不相等";
}

@Data注解

  • 1)生成无参构造方法;
  • 2)属性的set/get方法;
  • 3)equals(), hashCode(), toString(), canEqual()方法。
@Data(staticConstructor="of")
public class RumenzData {private Integer id;private String name;}
//等价于public class RumenzData {private Integer id;private String name;private RumenzData() {}public static RumenzData of() {return new RumenzData();}public Integer getId() {return this.id;}public String getName() {return this.name;}public void setId(final Integer id) {this.id = id;}public void setName(final String name) {this.name = name;}public boolean equals(final Object o) {if (o == this) {return true;} else if (!(o instanceof RumenzData)) {return false;} else {RumenzData other = (RumenzData)o;if (!other.canEqual(this)) {return false;} else {Object this$id = this.getId();Object other$id = other.getId();if (this$id == null) {if (other$id != null) {return false;}} else if (!this$id.equals(other$id)) {return false;}Object this$name = this.getName();Object 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;}}}protected boolean canEqual(final Object other) {return other instanceof RumenzData;}public int hashCode() {int PRIME = true;int result = 1;Object $id = this.getId();int result = result * 59 + ($id == null ? 43 : $id.hashCode());Object $name = this.getName();result = result * 59 + ($name == null ? 43 : $name.hashCode());return result;}public String toString() {return "RumenzData(id=" + this.getId() + ", name=" + this.getName() + ")";}
}
@GetMapping("/index4")
public String index4(){RumenzData of = RumenzData.of();of.setName("入门小站");String name = of.getName();return name;
}

@Cleanup注解

这个注解用在变量前面,可以保证此变量代表的资源会被自动关闭,默认是调用资源的close()方法,如果该资源有其它关闭方法,可使用@Cleanup(“methodName”)来指定要调用的方法,就用输入输出流来举个例子吧:

@GetMapping("/index5")
public String index5() throws IOException {File file = ResourceUtils.getFile("classpath:application.properties");@Cleanup  InputStream inputStream = new FileInputStream(file);byte b[]=new byte[(int) file.length()];inputStream.read(b);//@Cleanup 代替了 inputStream.close();return new String(b);
}

等价于

@GetMapping({"/index5"})
public String index5() throws IOException {File file = ResourceUtils.getFile("classpath:application.properties");FileInputStream inputStream = new FileInputStream(file);String var4;try {byte[] b = new byte[(int)file.length()];inputStream.read(b);var4 = new String(b);} finally {if (Collections.singletonList(inputStream).get(0) != null) {inputStream.close();}}return var4;
}

@NoArgsConstructor注解

@NoArgsConstructor在类上使用,它可以提供一个无参构造器

@NoArgsConstructor
public class RumenzNoArgsConstructor {private Integer id;private String name;
}

等价于


public class RumenzNoArgsConstructor {private Integer id;private String name;public RumenzNoArgsConstructor() {}
}

@RequiredArgsConstructor注解

指定final的属性生成构造方法

@ToString
@RequiredArgsConstructor
public class RumenzRequiredArgsConstructor {private Integer id;private final String name;
}

// 等价于

public class RumenzRequiredArgsConstructor {private Integer id;private final String name; //finalpublic String toString() {return "RumenzRequiredArgsConstructor(id=" + this.id + ", name=" + this.name + ")";}public RumenzRequiredArgsConstructor(final String name) {this.name = name;}
}

@AllArgsConstructor注解

类中所有的字段都生成一个有参的构造方法.

@ToString
@AllArgsConstructor
public class RumenzAllArgsConstructor {private  Integer id;private  String name;
}

//等价于

public class RumenzAllArgsConstructor {private Integer id;private String name;public String toString() {return "RumenzAllArgsConstructor(id=" + this.id + ", name=" + this.name + ")";}public RumenzAllArgsConstructor(final Integer id, final String name) {this.id = id;this.name = name;}
}

@Value注解

  • 1)有参构造方法;
  • 2)只添加@Value注解,没有其他限制,那么类属性会被编译成final的,因此只有get方法,而没有set方法。
@ToString
@Value
public class RumenzValue {private Integer id;private String name;
}

// 等价于

public final class RumenzValue {private final Integer id;private final String name;public RumenzValue(final Integer id, final String name) {this.id = id;this.name = name;}public Integer getId() {return this.id;}public String getName() {return this.name;}public boolean equals(final Object o) {if (o == this) {return true;} else if (!(o instanceof RumenzValue)) {return false;} else {RumenzValue other = (RumenzValue)o;Object this$id = this.getId();Object other$id = other.getId();if (this$id == null) {if (other$id != null) {return false;}} else if (!this$id.equals(other$id)) {return false;}Object this$name = this.getName();Object 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() {int PRIME = true;int result = 1;Object $id = this.getId();int result = result * 59 + ($id == null ? 43 : $id.hashCode());Object $name = this.getName();result = result * 59 + ($name == null ? 43 : $name.hashCode());return result;}public String toString() {return "RumenzValue(id=" + this.getId() + ", name=" + this.getName() + ")";}
}

@SneakyThrows注解

这个注解用在方法上,可以将方法中的代码用try-catch语句包裹起来,捕获异常并在catch中用Lombok.sneakyThrow(e)把异常抛出,可以使用@SneakyThrows(Exception.class)的形式指定抛出哪种异常,很简单的注解,直接看个例子:


@SneakyThrows
@GetMapping("/index9")
public String index9() {//使用@SneakyThrows就不用显式抛出异常了File file = ResourceUtils.getFile("classpath:application.properties");@Cleanup  InputStream inputStream = new FileInputStream(file);byte b[]=new byte[(int) file.length()];inputStream.read(b);//@Cleanup 代替了 inputStream.close();return new String(b);
}

// 等价于

@GetMapping({"/index9"})
public String index9() {try {File file = ResourceUtils.getFile("classpath:application.properties");FileInputStream inputStream = new FileInputStream(file);String var4;try {byte[] b = new byte[(int)file.length()];inputStream.read(b);var4 = new String(b);} finally {if (Collections.singletonList(inputStream).get(0) != null) {inputStream.close();}}return var4;} catch (Throwable var9) {throw var9;}
}

@Synchronized注解

synchronized是线程安全中一个重要的关键字,它是一种同步锁,主要用来保证在同一个时刻,只有一个线程可以执行某个方法或者某段代码块。一般使用synchronized去锁住代码块,而不是方法,因为锁住代码块效率更高。

public class RumenzSynchronized {private final Object readLock = new Object();@Synchronizedpublic static void hello() {System.out.println("rumenz.com");}@Synchronizedpublic int answerToLife() {return 110;}@Synchronized("readLock")public void foo() {System.out.println("入门小站");}
}

// 等价于

public class RumenzSynchronized {private static final Object $LOCK = new Object[0];private final Object $lock = new Object[0];private final Object readLock = new Object();public RumenzSynchronized() {}public static void hello() {synchronized($LOCK) {System.out.println("rumenz.com");}}public int answerToLife() {synchronized(this.$lock) {return 110;}}public void foo() {synchronized(this.readLock) {System.out.println("入门小站");}}
}

@Builder注解

用在类、构造器、方法上,为你提供复杂的builder APIs

@ToString
@Builder
public class RumenzBuilder {private Integer id;private String name;
}

// 等价于

public class RumenzBuilder {private Integer id;private String name;RumenzBuilder(final Integer id, final String name) {this.id = id;this.name = name;}public static RumenzBuilder.RumenzBuilderBuilder builder() {return new RumenzBuilder.RumenzBuilderBuilder();}public String toString() {return "RumenzBuilder(id=" + this.id + ", name=" + this.name + ")";}public static class RumenzBuilderBuilder {private Integer id;private String name;RumenzBuilderBuilder() {}public RumenzBuilder.RumenzBuilderBuilder id(final Integer id) {this.id = id;return this;}public RumenzBuilder.RumenzBuilderBuilder name(final String name) {this.name = name;return this;}public RumenzBuilder build() {return new RumenzBuilder(this.id, this.name);}public String toString() {return "RumenzBuilder.RumenzBuilderBuilder(id=" + this.id + ", name=" + this.name + ")";}}
}
@GetMapping("/index11")
public String index11() {RumenzBuilder rb=RumenzBuilder.builder().id(1).name("入门小站").build();return rb.toString();
}

@SuperBuilder

当实体类有集成关系时,需要用@SuperBuilder,否则调用的.builder都会报错.

@Builder并不支持父类成员属性的构造,@SuperBuilder注解的出现,就是用来解决这个问题。

使用@Builder或@SuperBuilder注解时,不会默认创建空参构造函数,如果你有额外使用空参构造函数或全参构造函数的需求,需要在子类和父类都加上以下注解:

本小结源码地址:

  • GitHub:https://github.com/mifunc/springboot/tree/main/lession13
  • Gitee:https://gitee.com/rumenz/springboot/tree/master/lession13
  • https://rumenz.com/rumenbiji/springboot-lombok.html

介绍

  • 我的博客 https://rumenz.com/ ,
  • 我的工具箱 https://tooltt.com/
  • 微信公众号:【入门小站】

  • 关注【入门小站】回复【1001】获取 linux常用命令速查手册
  • 关注【入门小站】回复【1003】获取 LeetCode题解【java语言实现】
  • 关注【入门小站】回复【1004】获取 Java基础核心总结
  • 关注【入门小站】回复【1009】获取 阿里巴巴Java开发手册

第十三节:使用Lombok简化你的代码相关推荐

  1. SpringBoot实战(一):使用Lombok简化你的代码

    [前言] Lombok是一个十分不错的工程,项目中引入它后可以使用注解来简化代码,比如最为常见的get.set.tostring等等: [如何使用]   一.项目POM中引入相应的Jar包 <d ...

  2. Idea使用Lombok简化实体类代码

    引入相应的maven包 <dependency><groupId>org.projectlombok</groupId><artifactId>lomb ...

  3. 使用Lombok简化你的代码

    http://www.cnblogs.com/ywqbj/p/5711691.html mavem <dependency> <groupId>org.projectlombo ...

  4. Spring学习笔记:尝试Lombok简化实体类代码

    文章目录 一.Lombok概述 二.安装Lombok插件 三.Lombok注解 (一)@Data (二)@Getter/@Setter (三)@NonNull (四)@Cleanup (五)@Equa ...

  5. Python编程基础:第二十三节 嵌套函数调用Nested Functions Calls

    第二十三节 嵌套函数调用Nested Functions Calls 前言 实践 前言 当一个函数的返回结果是另一个函数的输入的时候,我们就可以采用嵌套调用的方式来书写代码.举例来说,y=f(x)=x ...

  6. lombok 简化代码_如何编写更少,更好的代码,或Project Lombok

    lombok 简化代码 我长期以来一直打算写有关Lombok的文章 ,以至于每当一个自重的Java开发人员都已经听说过它时,我可能会写它. 尽管如此,值得一提的是,如果只是提醒自己,不要犹豫,尝试性能 ...

  7. Python编程基础:第五十三节 匿名函数Lambda Function

    第五十三节 匿名函数Lambda Function 前言 实践 前言 匿名函数是一种非常优雅的表达方式,它可以将函数定义用一行代码进行表示.其书写方式为参数列表:函数实现,其中多个参数之间用逗号隔开, ...

  8. Python编程基础:第四十三节 多继承Multiple Inheritance

    第四十三节 多继承Multiple Inheritance 前言 实践 前言 多继承是指一个子类可以拥有多个父类,其所有父类的属性和方法都能被其调用.其中多个父类之间用逗号隔开. 实践 我们先定义两个 ...

  9. Python编程基础:第三十三节 文件复制Copy a File

    第三十三节 文件复制Copy a File 前言 实践 前言 当我们需要将一个文件中的内容复制到另一个文件中时,就需要用到copyfile()函数,该函数一共有两个参数copyfile(src, ds ...

最新文章

  1. 【转载】使用Nexus搭建Maven服务器详细配置
  2. Linux下性能压测之系统参数调优
  3. 怎样用注解的方式配置Spring?
  4. ant-design-pro使用服务器数据接口代理配置
  5. leetcode590. N叉树的后序遍历
  6. yaml parse python_python-yaml
  7. stream去重_使用Java Stream API中DistinctBy删除重复数据
  8. JavaScript的求模、取整、小数的取舍
  9. Python验证码识别初探(tesserocr库)
  10. 《node.js开发指南》读后感
  11. MATLAB 中 floor、round、ceil、fix 取整函数的意义和区别
  12. 如何提高数据分析的效率
  13. 最新过浩方过VS魔兽1.24b全图工具发布
  14. C#:快速排序,有相同的数字会忽略,然后继续先前的寻找方向去找下一个满足要求的数字进行替换
  15. 【论文阅读】SyncPerf: Categorizing, Detecting, and Diagnosing Synchronization Performance Bugs
  16. 网络黑市规模达千亿元 信息泄露成最大安全威胁
  17. qmake 添加额外参数 分开编译
  18. 教你玩转 sqlplus,工作效率提升 200%
  19. Jqgird 如何使用自带的search模块进行数据查询
  20. 解题报告 (十三) 尺取法

热门文章

  1. 浅析gcc、arm-linux-gcc和arm-elf-gcc的关系-转
  2. rtsp简介(ZT)之消息流程-转
  3. VirtualBox 删掉虚拟镜像重新安装失败
  4. java 模拟 减法 进位_位运算实现加减乘除四则运算(Java)
  5. [Java] 蓝桥杯ALGO-113 算法训练 数的统计
  6. [Java] 蓝桥杯BASIC-13 基础练习 数列排序
  7. 蓝桥杯 ALGO-142 算法训练 P1103
  8. java数字计算结果_Java编写程序之输入一个数字实现该数字阶乘的计算
  9. weblogic启动项目失败查看_weblogic启动报错常见错误解决办法
  10. Python处理json字符串转化为字典