Lombok-入门篇

电玩女神 2023-01-10 14:31 238阅读 0赞

随着编程以及各种框架的发展,大大提供了开发的简洁和便利性。在开发过程中,我们经常要定义各种Bean,在Bean中会出现大量的getter、setter方法,有时还会重写toString等方法,比如:

  1. /**
  2. * @author javaerui
  3. * @Description:
  4. * @date 2021/1/22
  5. */
  6. public class User {
  7. public User() {
  8. }
  9. public User(String name, long id, Integer age, boolean vip, Boolean svip) {
  10. this.name = name;
  11. this.id = id;
  12. this.age = age;
  13. this.vip = vip;
  14. this.svip = svip;
  15. }
  16. private String name;
  17. private long id;
  18. private Integer age;
  19. private boolean vip;
  20. private Boolean svip;
  21. public String getName() {
  22. return name;
  23. }
  24. public void setName(String name) {
  25. this.name = name;
  26. }
  27. public long getId() {
  28. return id;
  29. }
  30. public void setId(long id) {
  31. this.id = id;
  32. }
  33. public Integer getAge() {
  34. return age;
  35. }
  36. public void setAge(Integer age) {
  37. this.age = age;
  38. }
  39. public boolean isVip() {
  40. return vip;
  41. }
  42. public void setVip(boolean vip) {
  43. this.vip = vip;
  44. }
  45. public Boolean getSvip() {
  46. return svip;
  47. }
  48. public void setSvip(Boolean svip) {
  49. this.svip = svip;
  50. }
  51. @Override
  52. public String toString() {
  53. return "User{" +
  54. "name='" + name + '\'' +
  55. ", id=" + id +
  56. ", age=" + age +
  57. ", vip=" + vip +
  58. ", svip=" + svip +
  59. '}';
  60. }
  61. }

大量的方法重置着整个类,让这个类看上去失去了很多美观性。于是,Lombok诞生了,我们只需要编写Bean的属性,然后使用Lombok提供的注解便能够完成getter、setter等方法的添加。对于JVM来说,它是只能够识别class字节码的,而我们程序员一般编写的java源码需要先编译成class字节码才能够被JVM识别并运行,所以Lombok是对class字节码做了文章,在.java文件的源码级别使用Lombok提供的注解,Lombok会在类编译成.class字节码的时候根据特定注解对类添加特定的方法,比如:

  1. /**
  2. * @author javaerui
  3. * @Description:
  4. * @date 2021/1/22
  5. */
  6. @NoArgsConstructor
  7. @AllArgsConstructor
  8. @Getter
  9. @Setter
  10. @ToString
  11. public class User {
  12. private String name;
  13. private long id;
  14. private Integer age;
  15. private boolean vip;
  16. private Boolean svip;
  17. }

编译User.java后,用IDEA打开编译生成的User.class内容:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. public class User {
  6. private String name;
  7. private long id;
  8. private Integer age;
  9. private boolean vip;
  10. private Boolean svip;
  11. public User() {
  12. }
  13. public User(String name, long id, Integer age, boolean vip, Boolean svip) {
  14. this.name = name;
  15. this.id = id;
  16. this.age = age;
  17. this.vip = vip;
  18. this.svip = svip;
  19. }
  20. public String getName() {
  21. return this.name;
  22. }
  23. public void setName(String name) {
  24. this.name = name;
  25. }
  26. public long getId() {
  27. return this.id;
  28. }
  29. public void setId(long id) {
  30. this.id = id;
  31. }
  32. public Integer getAge() {
  33. return this.age;
  34. }
  35. public void setAge(Integer age) {
  36. this.age = age;
  37. }
  38. public boolean isVip() {
  39. return this.vip;
  40. }
  41. public void setVip(boolean vip) {
  42. this.vip = vip;
  43. }
  44. public Boolean getSvip() {
  45. return this.svip;
  46. }
  47. public void setSvip(Boolean svip) {
  48. this.svip = svip;
  49. }
  50. public String toString() {
  51. return "User{name='" + this.name + '\'' + ", id=" + this.id + ", age=" + this.age + ", vip=" + this.vip + ", svip=" + this.svip + '}';
  52. }
  53. }

对User类使用了Lombok提供的注解后,类的内容实质上和上面没有使用Lombok的效果是一样的。从源码层对比两个类,使用Lombok注解后,看上去更加简洁明了了。


█ 简单使用

(1)IDEA安装Lombok插件:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUxODI3MQ_size_16_color_FFFFFF_t_70

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUxODI3MQ_size_16_color_FFFFFF_t_70 1

(2)引入依赖:

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. <version>1.18.16</version>
  5. <scope>provided</scope>
  6. </dependency>

(3)以User类为例,查看Lombok提供的注解所对应的方法。

  1. public class User {
  2. private String name;
  3. private long id;
  4. private Integer age;
  5. private boolean vip;
  6. private Boolean svip;
  7. }
  • @Getter

对Bean的属性构建标准getter方法。

源码:

  1. @Getter
  2. public class User {
  3. private String name;
  4. private long id;
  5. private Integer age;
  6. private boolean vip;
  7. private Boolean svip;
  8. }

编译后:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. public class User {
  6. private String name;
  7. private long id;
  8. private Integer age;
  9. private boolean vip;
  10. private Boolean svip;
  11. public User() {
  12. }
  13. public String getName() {
  14. return this.name;
  15. }
  16. public long getId() {
  17. return this.id;
  18. }
  19. public Integer getAge() {
  20. return this.age;
  21. }
  22. public boolean isVip() {
  23. return this.vip;
  24. }
  25. public Boolean getSvip() {
  26. return this.svip;
  27. }
  28. }
  • @Setter

对属性构建set方法。

源码:

  1. @Setter
  2. public class User {
  3. private String name;
  4. private long id;
  5. private Integer age;
  6. private boolean vip;
  7. private Boolean svip;
  8. }

编译后:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. public class User {
  6. private String name;
  7. private long id;
  8. private Integer age;
  9. private boolean vip;
  10. private Boolean svip;
  11. public User() {
  12. }
  13. public void setName(String name) {
  14. this.name = name;
  15. }
  16. public void setId(long id) {
  17. this.id = id;
  18. }
  19. public void setAge(Integer age) {
  20. this.age = age;
  21. }
  22. public void setVip(boolean vip) {
  23. this.vip = vip;
  24. }
  25. public void setSvip(Boolean svip) {
  26. this.svip = svip;
  27. }
  28. }
  • @ToString

重写toString方法。

源码:

  1. @ToString
  2. public class User {
  3. private String name;
  4. private long id;
  5. private Integer age;
  6. private boolean vip;
  7. private Boolean svip;
  8. }

编译后:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. public class User {
  6. private String name;
  7. private long id;
  8. private Integer age;
  9. private boolean vip;
  10. private Boolean svip;
  11. public User() {
  12. }
  13. public String toString() {
  14. return "User(name=" + this.name + ", id=" + this.id + ", age=" + this.age + ", vip=" + this.vip + ", svip=" + this.svip + ")";
  15. }
  16. }
  • @EqualsAndHashCode

重写equals与hashcode方法。

源码:

  1. @EqualsAndHashCode
  2. public class User {
  3. private String name;
  4. private long id;
  5. private Integer age;
  6. private boolean vip;
  7. private Boolean svip;
  8. }

编译后,从下面的方法可以看出,Lombok重写的方法会比较所有属性:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. public class User {
  6. private String name;
  7. private long id;
  8. private Integer age;
  9. private boolean vip;
  10. private Boolean svip;
  11. public User() {
  12. }
  13. public boolean equals(Object o) {
  14. if (o == this) {
  15. return true;
  16. } else if (!(o instanceof User)) {
  17. return false;
  18. } else {
  19. User other = (User)o;
  20. if (!other.canEqual(this)) {
  21. return false;
  22. } else if (this.id != other.id) {
  23. return false;
  24. } else if (this.vip != other.vip) {
  25. return false;
  26. } else {
  27. label52: {
  28. Object this$age = this.age;
  29. Object other$age = other.age;
  30. if (this$age == null) {
  31. if (other$age == null) {
  32. break label52;
  33. }
  34. } else if (this$age.equals(other$age)) {
  35. break label52;
  36. }
  37. return false;
  38. }
  39. Object this$svip = this.svip;
  40. Object other$svip = other.svip;
  41. if (this$svip == null) {
  42. if (other$svip != null) {
  43. return false;
  44. }
  45. } else if (!this$svip.equals(other$svip)) {
  46. return false;
  47. }
  48. Object this$name = this.name;
  49. Object other$name = other.name;
  50. if (this$name == null) {
  51. if (other$name != null) {
  52. return false;
  53. }
  54. } else if (!this$name.equals(other$name)) {
  55. return false;
  56. }
  57. return true;
  58. }
  59. }
  60. }
  61. protected boolean canEqual(Object other) {
  62. return other instanceof User;
  63. }
  64. public int hashCode() {
  65. int PRIME = true;
  66. int result = 1;
  67. long $id = this.id;
  68. int result = result * 59 + (int)($id >>> 32 ^ $id);
  69. result = result * 59 + (this.vip ? 79 : 97);
  70. Object $age = this.age;
  71. result = result * 59 + ($age == null ? 43 : $age.hashCode());
  72. Object $svip = this.svip;
  73. result = result * 59 + ($svip == null ? 43 : $svip.hashCode());
  74. Object $name = this.name;
  75. result = result * 59 + ($name == null ? 43 : $name.hashCode());
  76. return result;
  77. }
  78. }
  • @AllArgsConstructor、@NoArgsConstructor

@AllArgsConstructor构建全参构造器,@NoArgsConstructor构建无参构造器。

源码:

  1. @AllArgsConstructor
  2. @NoArgsConstructor
  3. public class User {
  4. private String name;
  5. private long id;
  6. private Integer age;
  7. private boolean vip;
  8. private Boolean svip;
  9. }

编译后:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. public class User {
  6. private String name;
  7. private long id;
  8. private Integer age;
  9. private boolean vip;
  10. private Boolean svip;
  11. public User(String name, long id, Integer age, boolean vip, Boolean svip) {
  12. this.name = name;
  13. this.id = id;
  14. this.age = age;
  15. this.vip = vip;
  16. this.svip = svip;
  17. }
  18. public User() {
  19. }
  20. }
  • @Builder

对Bean构建Builder构建者模式。

源码:

  1. @Builder
  2. public class User {
  3. private String name;
  4. private long id;
  5. private Integer age;
  6. private boolean vip;
  7. private Boolean svip;
  8. }

编译后:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. public class User {
  6. private String name;
  7. private long id;
  8. private Integer age;
  9. private boolean vip;
  10. private Boolean svip;
  11. User(String name, long id, Integer age, boolean vip, Boolean svip) {
  12. this.name = name;
  13. this.id = id;
  14. this.age = age;
  15. this.vip = vip;
  16. this.svip = svip;
  17. }
  18. public static User.UserBuilder builder() {
  19. return new User.UserBuilder();
  20. }
  21. public static class UserBuilder {
  22. private String name;
  23. private long id;
  24. private Integer age;
  25. private boolean vip;
  26. private Boolean svip;
  27. UserBuilder() {
  28. }
  29. public User.UserBuilder name(String name) {
  30. this.name = name;
  31. return this;
  32. }
  33. public User.UserBuilder id(long id) {
  34. this.id = id;
  35. return this;
  36. }
  37. public User.UserBuilder age(Integer age) {
  38. this.age = age;
  39. return this;
  40. }
  41. public User.UserBuilder vip(boolean vip) {
  42. this.vip = vip;
  43. return this;
  44. }
  45. public User.UserBuilder svip(Boolean svip) {
  46. this.svip = svip;
  47. return this;
  48. }
  49. public User build() {
  50. return new User(this.name, this.id, this.age, this.vip, this.svip);
  51. }
  52. public String toString() {
  53. return "User.UserBuilder(name=" + this.name + ", id=" + this.id + ", age=" + this.age + ", vip=" + this.vip + ", svip=" + this.svip + ")";
  54. }
  55. }
  56. }
  • @Cleanup

用于局部变量,会调用变量的close方法来关闭资源。@Cleanup标记的局部变量,必须具有close方法。

源码:

  1. public void method() throws IOException {
  2. @Cleanup FileOutputStream fileOutputStream = new FileOutputStream("E:\\Downloads\\java.txt");
  3. fileOutputStream.write("Hello World".getBytes());
  4. }

编译后:

  1. public void method() throws IOException {
  2. FileOutputStream fileOutputStream = new FileOutputStream("E:\\Downloads\\java.txt");
  3. try {
  4. fileOutputStream.write("Hello World".getBytes());
  5. } finally {
  6. if (Collections.singletonList(fileOutputStream).get(0) != null) {
  7. fileOutputStream.close();
  8. }
  9. }
  10. }
  • @NonNull

非空检查,当设置的值为空时,会抛异常。

  1. public void setName(@NonNull String name) {
  2. this.name = name;
  3. }

调用,对name进行赋值为null:

  1. User user = new User();
  2. user.setName(null);

抛异常:

20210124180253286.png

  • @RequiredArgsConstructor

对标记了@NonNull的属性构建有参构造器。

源码:

  1. @RequiredArgsConstructor
  2. public class User {
  3. @NonNull
  4. private String name;
  5. private long id;
  6. private Integer age;
  7. @NonNull
  8. private boolean vip;
  9. private Boolean svip;
  10. }

编译后,从这里可以看出@NonNull标注的字段会加非空判断:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. import lombok.NonNull;
  6. public class User {
  7. @NonNull
  8. private String name;
  9. private long id;
  10. private Integer age;
  11. @NonNull
  12. private boolean vip;
  13. private Boolean svip;
  14. public User(@NonNull String name, @NonNull boolean vip) {
  15. if (name == null) {
  16. throw new NullPointerException("name is marked non-null but is null");
  17. } else {
  18. this.name = name;
  19. this.vip = vip;
  20. }
  21. }
  22. }
  • @Data

作用是@Getter、@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor的聚合。

源码:

  1. @Data
  2. public class User {
  3. private String name;
  4. private long id;
  5. private Integer age;
  6. private boolean vip;
  7. private Boolean svip;
  8. }

编译后:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. import java.util.List;
  6. import lombok.NonNull;
  7. public class User {
  8. @NonNull
  9. private String name;
  10. private long id;
  11. private Integer age;
  12. private boolean vip;
  13. private Boolean svip;
  14. private List<String> list;
  15. public User(@NonNull String name) {
  16. if (name == null) {
  17. throw new NullPointerException("name is marked non-null but is null");
  18. } else {
  19. this.name = name;
  20. }
  21. }
  22. @NonNull
  23. public String getName() {
  24. return this.name;
  25. }
  26. public long getId() {
  27. return this.id;
  28. }
  29. public Integer getAge() {
  30. return this.age;
  31. }
  32. public boolean isVip() {
  33. return this.vip;
  34. }
  35. public Boolean getSvip() {
  36. return this.svip;
  37. }
  38. public List<String> getList() {
  39. return this.list;
  40. }
  41. public void setName(@NonNull String name) {
  42. if (name == null) {
  43. throw new NullPointerException("name is marked non-null but is null");
  44. } else {
  45. this.name = name;
  46. }
  47. }
  48. public void setId(long id) {
  49. this.id = id;
  50. }
  51. public void setAge(Integer age) {
  52. this.age = age;
  53. }
  54. public void setVip(boolean vip) {
  55. this.vip = vip;
  56. }
  57. public void setSvip(Boolean svip) {
  58. this.svip = svip;
  59. }
  60. public void setList(List<String> list) {
  61. this.list = list;
  62. }
  63. public boolean equals(Object o) {
  64. if (o == this) {
  65. return true;
  66. } else if (!(o instanceof User)) {
  67. return false;
  68. } else {
  69. User other = (User)o;
  70. if (!other.canEqual(this)) {
  71. return false;
  72. } else if (this.getId() != other.getId()) {
  73. return false;
  74. } else if (this.isVip() != other.isVip()) {
  75. return false;
  76. } else {
  77. label64: {
  78. Object this$age = this.getAge();
  79. Object other$age = other.getAge();
  80. if (this$age == null) {
  81. if (other$age == null) {
  82. break label64;
  83. }
  84. } else if (this$age.equals(other$age)) {
  85. break label64;
  86. }
  87. return false;
  88. }
  89. label57: {
  90. Object this$svip = this.getSvip();
  91. Object other$svip = other.getSvip();
  92. if (this$svip == null) {
  93. if (other$svip == null) {
  94. break label57;
  95. }
  96. } else if (this$svip.equals(other$svip)) {
  97. break label57;
  98. }
  99. return false;
  100. }
  101. Object this$name = this.getName();
  102. Object other$name = other.getName();
  103. if (this$name == null) {
  104. if (other$name != null) {
  105. return false;
  106. }
  107. } else if (!this$name.equals(other$name)) {
  108. return false;
  109. }
  110. Object this$list = this.getList();
  111. Object other$list = other.getList();
  112. if (this$list == null) {
  113. if (other$list != null) {
  114. return false;
  115. }
  116. } else if (!this$list.equals(other$list)) {
  117. return false;
  118. }
  119. return true;
  120. }
  121. }
  122. }
  123. protected boolean canEqual(Object other) {
  124. return other instanceof User;
  125. }
  126. public int hashCode() {
  127. int PRIME = true;
  128. int result = 1;
  129. long $id = this.getId();
  130. int result = result * 59 + (int)($id >>> 32 ^ $id);
  131. result = result * 59 + (this.isVip() ? 79 : 97);
  132. Object $age = this.getAge();
  133. result = result * 59 + ($age == null ? 43 : $age.hashCode());
  134. Object $svip = this.getSvip();
  135. result = result * 59 + ($svip == null ? 43 : $svip.hashCode());
  136. Object $name = this.getName();
  137. result = result * 59 + ($name == null ? 43 : $name.hashCode());
  138. Object $list = this.getList();
  139. result = result * 59 + ($list == null ? 43 : $list.hashCode());
  140. return result;
  141. }
  142. public String toString() {
  143. return "User(name=" + this.getName() + ", id=" + this.getId() + ", age=" + this.getAge() + ", vip=" + this.isVip() + ", svip=" + this.getSvip() + ", list=" + this.getList() + ")";
  144. }
  145. }
  • @SneakyThrows

标记方法抛出的异常。

源码:

  1. @SneakyThrows(IOException.class)
  2. public void method() {
  3. FileOutputStream fileOutputStream = new FileOutputStream("E:\\Downloads\\java.txt");
  4. fileOutputStream.write("Hello World".getBytes());
  5. }

编译后:

  1. public void method() {
  2. try {
  3. FileOutputStream fileOutputStream = new FileOutputStream("E:\\Downloads\\java.txt");
  4. fileOutputStream.write("Hello World".getBytes());
  5. } catch (IOException var2) {
  6. throw var2;
  7. }
  8. }
  • @Synchronized

对方法体进行同步操作。

源码:

  1. @Synchronized
  2. public void method() throws IOException{
  3. FileOutputStream fileOutputStream = new FileOutputStream("E:\\Downloads\\java.txt");
  4. fileOutputStream.write("Hello World".getBytes());
  5. }

编译后:

  1. private final Object $lock = new Object[0];
  2. public void method() throws IOException {
  3. synchronized(this.$lock) {
  4. FileOutputStream fileOutputStream = new FileOutputStream("E:\\Downloads\\java.txt");
  5. fileOutputStream.write("Hello World".getBytes());
  6. }
  7. }
  • @Value

构建一个final修饰的类,并提供全参构造器,getter方法,重新equals、hashcode、toString方法。

源码:

  1. @Value
  2. public class User {
  3. private String name;
  4. private long id;
  5. private Integer age;
  6. private boolean vip;
  7. private Boolean svip;
  8. }

编译后:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. public final class User {
  6. private final String name;
  7. private final long id;
  8. private final Integer age;
  9. private final boolean vip;
  10. private final Boolean svip;
  11. public User(String name, long id, Integer age, boolean vip, Boolean svip) {
  12. this.name = name;
  13. this.id = id;
  14. this.age = age;
  15. this.vip = vip;
  16. this.svip = svip;
  17. }
  18. public String getName() {
  19. return this.name;
  20. }
  21. public long getId() {
  22. return this.id;
  23. }
  24. public Integer getAge() {
  25. return this.age;
  26. }
  27. public boolean isVip() {
  28. return this.vip;
  29. }
  30. public Boolean getSvip() {
  31. return this.svip;
  32. }
  33. public boolean equals(Object o) {
  34. if (o == this) {
  35. return true;
  36. } else if (!(o instanceof User)) {
  37. return false;
  38. } else {
  39. User other = (User)o;
  40. if (this.getId() != other.getId()) {
  41. return false;
  42. } else if (this.isVip() != other.isVip()) {
  43. return false;
  44. } else {
  45. label49: {
  46. Object this$age = this.getAge();
  47. Object other$age = other.getAge();
  48. if (this$age == null) {
  49. if (other$age == null) {
  50. break label49;
  51. }
  52. } else if (this$age.equals(other$age)) {
  53. break label49;
  54. }
  55. return false;
  56. }
  57. Object this$svip = this.getSvip();
  58. Object other$svip = other.getSvip();
  59. if (this$svip == null) {
  60. if (other$svip != null) {
  61. return false;
  62. }
  63. } else if (!this$svip.equals(other$svip)) {
  64. return false;
  65. }
  66. Object this$name = this.getName();
  67. Object other$name = other.getName();
  68. if (this$name == null) {
  69. if (other$name != null) {
  70. return false;
  71. }
  72. } else if (!this$name.equals(other$name)) {
  73. return false;
  74. }
  75. return true;
  76. }
  77. }
  78. }
  79. public int hashCode() {
  80. int PRIME = true;
  81. int result = 1;
  82. long $id = this.getId();
  83. int result = result * 59 + (int)($id >>> 32 ^ $id);
  84. result = result * 59 + (this.isVip() ? 79 : 97);
  85. Object $age = this.getAge();
  86. result = result * 59 + ($age == null ? 43 : $age.hashCode());
  87. Object $svip = this.getSvip();
  88. result = result * 59 + ($svip == null ? 43 : $svip.hashCode());
  89. Object $name = this.getName();
  90. result = result * 59 + ($name == null ? 43 : $name.hashCode());
  91. return result;
  92. }
  93. public String toString() {
  94. return "User(name=" + this.getName() + ", id=" + this.getId() + ", age=" + this.getAge() + ", vip=" + this.isVip() + ", svip=" + this.getSvip() + ")";
  95. }
  96. }
  • @With

构建一个withXX的方法,实现将参数比较,如果是相等,返回当前对象,如果不等,创建新的对象。@With标记的类必须提供一个全参构造器,否则无法编译通过(为什么呢?看完编译后的源码就清楚了)。

源码:

  1. @AllArgsConstructor
  2. @With
  3. public class User {
  4. private String name;
  5. public User(String name) {
  6. this.name = name;
  7. }
  8. private long id;
  9. private Integer age;
  10. private boolean vip;
  11. private Boolean svip;
  12. }

编译后:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. public class User {
  6. private String name;
  7. private long id;
  8. private Integer age;
  9. private boolean vip;
  10. private Boolean svip;
  11. public User(String name) {
  12. this.name = name;
  13. }
  14. public User(String name, long id, Integer age, boolean vip, Boolean svip) {
  15. this.name = name;
  16. this.id = id;
  17. this.age = age;
  18. this.vip = vip;
  19. this.svip = svip;
  20. }
  21. public User withName(String name) {
  22. // 通过new User的全参构造器创建对象的,所以必须提供一个全参构造器
  23. return this.name == name ? this : new User(name, this.id, this.age, this.vip, this.svip);
  24. }
  25. public User withId(long id) {
  26. return this.id == id ? this : new User(this.name, id, this.age, this.vip, this.svip);
  27. }
  28. public User withAge(Integer age) {
  29. return this.age == age ? this : new User(this.name, this.id, age, this.vip, this.svip);
  30. }
  31. public User withVip(boolean vip) {
  32. return this.vip == vip ? this : new User(this.name, this.id, this.age, vip, this.svip);
  33. }
  34. public User withSvip(Boolean svip) {
  35. return this.svip == svip ? this : new User(this.name, this.id, this.age, this.vip, svip);
  36. }
  37. }
  • var、val

声明局部变量。

源码:

  1. public void method() {
  2. var x = 10;
  3. val y = 1.1;
  4. var list = new ArrayList<>();
  5. list.add("hello world");
  6. }

编译后:

  1. public void method() {
  2. int x = true;
  3. double y = 1.1D;
  4. ArrayList<Object> list = new ArrayList();
  5. list.add("hello world");
  6. }
  • @CommonsLog

日志相关,构建log字段,类型为org.apache.commons.logging.Log。使用的时候要引入相对应的日志依赖。

源码:

  1. @CommonsLog
  2. public class User {
  3. }

编译后:

  1. public class User {
  2. private static final org.apache.commons.logging.Log log =
  3. org.apache.commons.logging.LogFactory.getLog(User.class);
  4. }
  • @Flogger、@JBossLog、@Log、@Log4j、@Log4j2、@Slf4j、@XSlf4j

和@CommonsLog一样都是日志相关,区别是Log类型不同。

@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(User.class);

@Log:

private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(User.class.getName());

@Log4j:

private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(User.class);

@Log4j2:

private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(User.class);

@Slf4j:

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(User.class);

@XSlf4j:

private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(User.class);


关于Lombok的详细介绍,请戳《Lombok-高级篇》

发表评论

表情:
评论列表 (有 0 条评论,238人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Lombok-入门

    随着编程以及各种框架的发展,大大提供了开发的简洁和便利性。在开发过程中,我们经常要定义各种Bean,在Bean中会出现大量的getter、setter方法,有时还会重写toSt

    相关 SpringBoot 第一入门

    前言   博主从去年开始,项目中使用的框架逐渐被 SpringBoot 取代。今年独立负责的两个项目也都是用 SpringBoot ,看过不少资料、博客。网上的资源,内容