Lombok

作用:帮使用者提高编码效率,减少重复与冗余的代码

原理:ASM 动态修改class文件


配置

maven

依赖

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. <version>1.16.8</version>
  5. </dependency>

编译

  1. <build>
  2. <plugins>
  3. <plugin>
  4. <groupId>org.projectlombok</groupId>
  5. <artifactId>lombok-maven-plugin</artifactId>
  6. <version>1.16.6.1</version>
  7. </plugin>
  8. </plugins>
  9. </build>

idea

  • 安装插件
    lombok 基础教程 - 图1

常用注解:

java bean相关

@Setter

  • 功能

生成setter方法

  • 源码
  1. @Setter
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. public void setId(Integer id) {
  8. this.id = id;
  9. }
  10. public void setName(String name) {
  11. this.name = name;
  12. }
  13. }

@Getter

  • 功能

生成getter方法

  • 源码
  1. @Getter
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. public Integer getId() {
  8. return this.id;
  9. }
  10. public String getName() {
  11. return this.name;
  12. }
  13. }

@ToString

  • 功能

生成toString方法

  • 源码
  1. @ToString
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. public String toString() {
  8. return "LombokDemo(id=" + this.id + ", name=" + this.name + ")";
  9. }
  10. }

@Getter(lazy = true)

  • 功能

懒加载属性

  • 注意:

这个与上面@Getter不同,那个是修饰在类上的,也可以修饰在属性上。如果有lazy=true只能修饰在属性,并且还要是private final修饰,限制很大

  • 编码
  1. public class LombokDemo {
  2. @Getter(lazy = true) private final List<Integer> ids = Arrays.asList(1, 2, 3, 4);
  3. private String name;
  4. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import java.util.Arrays;
  3. import java.util.List;
  4. import java.util.concurrent.atomic.AtomicReference;
  5. public class LombokDemo {
  6. private final AtomicReference<Object> ids = new AtomicReference();
  7. private String name;
  8. public LombokDemo() {
  9. }
  10. public List<Integer> getIds() {
  11. Object value = this.ids.get();
  12. if(value == null) {
  13. AtomicReference var2 = this.ids;
  14. synchronized(this.ids) {
  15. value = this.ids.get();
  16. if(value == null) {
  17. List actualValue = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4)});
  18. value = actualValue == null?this.ids:actualValue;
  19. this.ids.set(value);
  20. }
  21. }
  22. }
  23. return (List)((List)(value == this.ids?null:value));
  24. }
  25. }

@EqualsAndHashCode

  • 功能

生成equals方法与hashCode方法

  • 源码
  1. @EqualsAndHashCode
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. public boolean equals(Object o) {
  8. if(o == this) {
  9. return true;
  10. } else if(!(o instanceof LombokDemo)) {
  11. return false;
  12. } else {
  13. LombokDemo other = (LombokDemo)o;
  14. if(!other.canEqual(this)) {
  15. return false;
  16. } else {
  17. Integer this$id = this.id;
  18. Integer other$id = other.id;
  19. if(this$id == null) {
  20. if(other$id != null) {
  21. return false;
  22. }
  23. } else if(!this$id.equals(other$id)) {
  24. return false;
  25. }
  26. String this$name = this.name;
  27. String other$name = other.name;
  28. if(this$name == null) {
  29. if(other$name != null) {
  30. return false;
  31. }
  32. } else if(!this$name.equals(other$name)) {
  33. return false;
  34. }
  35. return true;
  36. }
  37. }
  38. }
  39. protected boolean canEqual(Object other) {
  40. return other instanceof LombokDemo;
  41. }
  42. public int hashCode() {
  43. boolean PRIME = true;
  44. byte result = 1;
  45. Integer $id = this.id;
  46. int result1 = result * 59 + ($id == null?43:$id.hashCode());
  47. String $name = this.name;
  48. result1 = result1 * 59 + ($name == null?43:$name.hashCode());
  49. return result1;
  50. }
  51. }

@NoAragsConstructor

  • 功能

添加一个无参构造函数

  • 注意

这个注解在没有其它有参构造函数的情况下使用意义不大,因为在这种情况下java默认会添加一个无参构造函数

  • 源码
  1. @NoArgsConstructor
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. }

@AllArgsConstructor

  • 功能

添加一个所有参数的构造函数

  • 源码
  1. @AllArgsConstructor
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import java.beans.ConstructorProperties;
  3. public class LombokDemo {
  4. private Integer id;
  5. private String name;
  6. @ConstructorProperties({"id", "name"})
  7. public LombokDemo(Integer id, String name) {
  8. this.id = id;
  9. this.name = name;
  10. }
  11. }

@RequiredArgsConstructor

  • 功能

生成一个包含必填参数的构造函数

  • 注意

要与@NonNull 搭配使用,该注解修饰的属性就是必填参数

  • 源码
  1. @RequiredArgsConstructor
  2. public class LombokDemo {
  3. @NonNull private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import java.beans.ConstructorProperties;
  3. import lombok.NonNull;
  4. public class LombokDemo {
  5. @NonNull
  6. private Integer id;
  7. private String name;
  8. @ConstructorProperties({"id"})
  9. public LombokDemo(@NonNull Integer id) {
  10. if(id == null) {
  11. throw new NullPointerException("id");
  12. } else {
  13. this.id = id;
  14. }
  15. }
  16. }

@Data

  • 功能

这是一个综合注解了,等于同时使用

@Getter, @Setter, @ToString, @EqualsAndHashCode,@RequiredArgsConstructor

  • 源码
  1. @Data
  2. public class LombokDemo {
  3. @NonNull private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. public Integer getId() {
  8. return this.id;
  9. }
  10. public String getName() {
  11. return this.name;
  12. }
  13. public void setId(Integer id) {
  14. this.id = id;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public boolean equals(Object o) {
  20. if(o == this) {
  21. return true;
  22. } else if(!(o instanceof LombokDemo)) {
  23. return false;
  24. } else {
  25. LombokDemo other = (LombokDemo)o;
  26. if(!other.canEqual(this)) {
  27. return false;
  28. } else {
  29. Integer this$id = this.getId();
  30. Integer other$id = other.getId();
  31. if(this$id == null) {
  32. if(other$id != null) {
  33. return false;
  34. }
  35. } else if(!this$id.equals(other$id)) {
  36. return false;
  37. }
  38. String this$name = this.getName();
  39. String other$name = other.getName();
  40. if(this$name == null) {
  41. if(other$name != null) {
  42. return false;
  43. }
  44. } else if(!this$name.equals(other$name)) {
  45. return false;
  46. }
  47. return true;
  48. }
  49. }
  50. }
  51. protected boolean canEqual(Object other) {
  52. return other instanceof LombokDemo;
  53. }
  54. public int hashCode() {
  55. boolean PRIME = true;
  56. byte result = 1;
  57. Integer $id = this.getId();
  58. int result1 = result * 59 + ($id == null?43:$id.hashCode());
  59. String $name = this.getName();
  60. result1 = result1 * 59 + ($name == null?43:$name.hashCode());
  61. return result1;
  62. }
  63. public String toString() {
  64. return "LombokDemo(id=" + this.getId() + ", name=" + this.getName() + ")";
  65. }
  66. }

@Value

  • 功能

不可变类的@Data, 他会默认给属性加上final

  • 源码
  1. @Value
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import java.beans.ConstructorProperties;
  3. public final class LombokDemo {
  4. private final Integer id;
  5. private final String name;
  6. @ConstructorProperties({"id", "name"})
  7. public LombokDemo(Integer id, String name) {
  8. this.id = id;
  9. this.name = name;
  10. }
  11. public Integer getId() {
  12. return this.id;
  13. }
  14. public String getName() {
  15. return this.name;
  16. }
  17. public boolean equals(Object o) {
  18. if(o == this) {
  19. return true;
  20. } else if(!(o instanceof LombokDemo)) {
  21. return false;
  22. } else {
  23. LombokDemo other = (LombokDemo)o;
  24. Integer this$id = this.getId();
  25. Integer other$id = other.getId();
  26. if(this$id == null) {
  27. if(other$id != null) {
  28. return false;
  29. }
  30. } else if(!this$id.equals(other$id)) {
  31. return false;
  32. }
  33. String this$name = this.getName();
  34. String other$name = other.getName();
  35. if(this$name == null) {
  36. if(other$name != null) {
  37. return false;
  38. }
  39. } else if(!this$name.equals(other$name)) {
  40. return false;
  41. }
  42. return true;
  43. }
  44. }
  45. public int hashCode() {
  46. boolean PRIME = true;
  47. byte result = 1;
  48. Integer $id = this.getId();
  49. int result1 = result * 59 + ($id == null?43:$id.hashCode());
  50. String $name = this.getName();
  51. result1 = result1 * 59 + ($name == null?43:$name.hashCode());
  52. return result1;
  53. }
  54. public String toString() {
  55. return "LombokDemo(id=" + this.getId() + ", name=" + this.getName() + ")";
  56. }
  57. }

@Accessors

  • 功能

这个注解要搭配@Getter与@Setter使用,用来修改默认的setter与getter方法的形式

  • 注意

@Accessors有三个参数可以使用

  1. chain 链式的形式

  2. fluent 流式的形式

  3. prefix 生成指定前缀的属性的getter与setter方法,并且生成的getter与setter方法时会去除前缀

  • 源码 chain = true
  1. @Accessors(chain = true)
  2. @Setter
  3. @Getter
  4. public class LombokDemo {
  5. private Integer id;
  6. private String name;
  7. }
  • 编译后 chain = true
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. public LombokDemo setId(Integer id) {
  8. this.id = id;
  9. return this;
  10. }
  11. public LombokDemo setName(String name) {
  12. this.name = name;
  13. return this;
  14. }
  15. public Integer getId() {
  16. return this.id;
  17. }
  18. public String getName() {
  19. return this.name;
  20. }
  21. }
  • 源码 fluent = true
  1. @Accessors(fluent = true)
  2. @Setter
  3. @Getter
  4. public class LombokDemo {
  5. private Integer id;
  6. private String name;
  7. }
  • 编译后 fluent = true
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. public LombokDemo id(Integer id) {
  8. this.id = id;
  9. return this;
  10. }
  11. public LombokDemo name(String name) {
  12. this.name = name;
  13. return this;
  14. }
  15. public Integer id() {
  16. return this.id;
  17. }
  18. public String name() {
  19. return this.name;
  20. }
  21. }
  • 源码 prefix = "xxx"
  1. @Accessors(prefix = "xxx")
  2. @Setter
  3. @Getter
  4. public class LombokDemo {
  5. private Integer xxxId;
  6. private String name;
  7. }
  • 编译后 prefix = "xxx"
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer xxxId;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. public void setId(Integer xxxId) {
  8. this.xxxId = xxxId;
  9. }
  10. public Integer getId() {
  11. return this.xxxId;
  12. }
  13. }

其它注解:

日志相关

@Log4j

  • 源码
  1. @Log4j
  2. public class LombokDemo {
  3. private Integer xxxId;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import org.apache.log4j.Logger;
  3. public class LombokDemo {
  4. private static final Logger log = Logger.getLogger(LombokDemo.class);
  5. private Integer xxxId;
  6. private String name;
  7. public LombokDemo() {
  8. }
  9. }

@CommonsLog

  • 源码
  1. @CommonsLog
  2. public class LombokDemo {
  3. private Integer xxxId;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import org.apache.commons.logging.Log;
  3. import org.apache.commons.logging.LogFactory;
  4. public class LombokDemo {
  5. private static final Log log = LogFactory.getLog(LombokDemo.class);
  6. private Integer xxxId;
  7. private String name;
  8. public LombokDemo() {
  9. }
  10. }

@Log

  • 源码
  1. @Log
  2. public class LombokDemo {
  3. private Integer xxxId;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import java.util.logging.Logger;
  3. public class LombokDemo {
  4. private static final Logger log = Logger.getLogger(LombokDemo.class.getName());
  5. private Integer xxxId;
  6. private String name;
  7. public LombokDemo() {
  8. }
  9. }

@Log4j2

  • 源码
  1. @Log4j2
  2. public class LombokDemo {
  3. private Integer xxxId;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import org.apache.logging.log4j.LogManager;
  3. import org.apache.logging.log4j.Logger;
  4. public class LombokDemo {
  5. private static final Logger log = LogManager.getLogger(LombokDemo.class);
  6. private Integer xxxId;
  7. private String name;
  8. public LombokDemo() {
  9. }
  10. }

@Slf4j

  • 源码
  1. @Slf4j
  2. public class LombokDemo {
  3. private Integer xxxId;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. public class LombokDemo {
  5. private static final Logger log = LoggerFactory.getLogger(LombokDemo.class);
  6. private Integer xxxId;
  7. private String name;
  8. public LombokDemo() {
  9. }
  10. }

设计模式相关

@Builder

  • 功能

通过建造者模块来生成bean

  • 源码
  1. @Builder
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. LombokDemo(Integer id, String name) {
  6. this.id = id;
  7. this.name = name;
  8. }
  9. public static LombokDemo.LombokDemoBuilder builder() {
  10. return new LombokDemo.LombokDemoBuilder();
  11. }
  12. public static class LombokDemoBuilder {
  13. private Integer id;
  14. private String name;
  15. LombokDemoBuilder() {
  16. }
  17. public LombokDemo.LombokDemoBuilder id(Integer id) {
  18. this.id = id;
  19. return this;
  20. }
  21. public LombokDemo.LombokDemoBuilder name(String name) {
  22. this.name = name;
  23. return this;
  24. }
  25. public LombokDemo build() {
  26. return new LombokDemo(this.id, this.name);
  27. }
  28. public String toString() {
  29. return "LombokDemo.LombokDemoBuilder(id=" + this.id + ", name=" + this.name + ")";
  30. }
  31. }
  32. }

@Delegate

  • 功能

@Delegate注释的属性,会把这个属性对象的公有非静态方法合到当前类

  • 注意

公共 非静态方法

  • 源码
  1. public class LombokDemo {
  2. @Delegate
  3. private Integer id;
  4. private String name;
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. public class LombokDemo {
  3. private Integer id;
  4. private String name;
  5. public LombokDemo() {
  6. }
  7. public byte byteValue() {
  8. return this.id.byteValue();
  9. }
  10. public short shortValue() {
  11. return this.id.shortValue();
  12. }
  13. public int intValue() {
  14. return this.id.intValue();
  15. }
  16. public long longValue() {
  17. return this.id.longValue();
  18. }
  19. public float floatValue() {
  20. return this.id.floatValue();
  21. }
  22. public double doubleValue() {
  23. return this.id.doubleValue();
  24. }
  25. public int compareTo(Integer arg0) {
  26. return this.id.compareTo(arg0);
  27. }
  28. }

工具相关

@Cleanup

  • 功能

关闭流

  • 注意

关闭流的方式有点怪异,而且没有在finally里面关闭,如果出现异常的就不会关闭了

  • 源码
  1. public class LombokDemo {
  2. public void test() throws IOException {
  3. @Cleanup InputStream inputStream = new FileInputStream("xxx.txt");
  4. }
  5. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. import java.util.Collections;
  5. public class LombokDemo {
  6. public LombokDemo() {
  7. }
  8. public void test() throws IOException {
  9. FileInputStream inputStream = new FileInputStream("xxx.txt");
  10. if(Collections.singletonList(inputStream).get(0) != null) {
  11. inputStream.close();
  12. }
  13. }
  14. }

@Synchronized

  • 功能

给方法加一个同步块

  • 源码
  1. public class LombokDemo {
  2. @Synchronized
  3. public void test() throws IOException {
  4. System.out.println("test");
  5. }
  6. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import java.io.IOException;
  3. public class LombokDemo {
  4. private final Object $lock = new Object[0];
  5. public LombokDemo() {
  6. }
  7. public void test() throws IOException {
  8. Object var1 = this.$lock;
  9. synchronized(this.$lock) {
  10. System.out.println("test");
  11. }
  12. }
  13. }

@SneakyThrows

  • 功能

忽略异常

  • 源码
  1. public class LombokDemo {
  2. @SneakyThrows
  3. public void test() {
  4. String s = new String("test".getBytes(), "utf-8");
  5. }
  6. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import java.io.IOException;
  3. public class LombokDemo {
  4. private final Object $lock = new Object[0];
  5. public LombokDemo() {
  6. }
  7. public void test() throws IOException {
  8. Object var1 = this.$lock;
  9. synchronized(this.$lock) {
  10. System.out.println("test");
  11. }
  12. }
  13. }

@NonNull

  • 功能

设置不能为空的参数

  • 源码
  1. public class LombokDemo {
  2. public void test(@NonNull String val) {
  3. }
  4. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. import lombok.NonNull;
  3. public class LombokDemo {
  4. public LombokDemo() {
  5. }
  6. public void test(@NonNull String val) {
  7. if(val == null) {
  8. throw new NullPointerException("val");
  9. }
  10. }
  11. }

@UtilityClass

  • 功能

把普通类转为工具类

  • 源码
  1. @UtilityClass
  2. public class LombokDemo {
  3. private Integer id = 1;
  4. private String name = "kiwi";
  5. public void util(){
  6. System.out.println("xxx");
  7. }
  8. }
  • 编译后
  1. package xyz.mrwood.study.lombok;
  2. public final class LombokDemo {
  3. private static Integer id = Integer.valueOf(1);
  4. private static String name = "kiwi";
  5. public static void util() {
  6. System.out.println("xxx");
  7. }
  8. private LombokDemo() {
  9. throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
  10. }
  11. }