SpringBoot - Lombok使用详解2(@Setter、@Getter、@ToString、@EqualsAndHashCode)
四、Lombok 注解详解(1)
1,@Setter 和 @Getter
(1)这两个注解用于生成 setter 和 getter 方法,可以用在类或者属性上:
- 如果用在属性上:则只为该属性提供 setter 和 getter 方法
- 如果是用在类上:则为这个类所有属性供 setter 和 getter方法
(2)下面我们在一个类上添加 @Setter 和 @Getter 注解:
import lombok.Getter; import lombok.Setter; @Getter @Setter public class User { private String name; private Integer age; }
(3)然后我们就可以直接使用它的 setter 和 getter 方法了:
User user = new User(); user.setName("hangge"); user.setAge(123); user.getName(); user.getAge();
2,@Getter(lazy=true)
(1)该标注用于生成一个 lazy 版的 getter,它会在第一次调用这个 getter 时计算一次值,然后从那里开始缓存它。如果计算该值需要大量 CPU,或者该值占用大量内存,这可能很有用。
注意:Lombok 会自动去管理线程安全的问题,所以不会存在重复赋值的问题。
(2)要使用此功能,需要创建一个 private final 变量,并且使用运行成本高的表达式对其进行初始化,同时使用 @Getter(lazy=true) 注解进行标注。
// 使用注解 public class GetterLazyExample { @Getter(lazy=true) private final double[] cached = expensive(); private double[] expensive() { double[] result = new double[1000000]; for (int i = 0; i < result.length; i++) { result[i] = Math.asin(i); } return result; } } // 不使用注解 public class GetterLazyExample { private final java.util.concurrent.AtomicReference<java.lang.Object> cached = new java.util.concurrent.AtomicReference<java.lang.Object>(); public double[] getCached() { java.lang.Object value = this.cached.get(); if (value == null) { synchronized(this.cached) { value = this.cached.get(); if (value == null) { final double[] actualValue = expensive(); value = actualValue == null ? this.cached : actualValue; this.cached.set(value); } } } return (double[])(value == this.cached ? null : value); } private double[] expensive() { double[] result = new double[1000000]; for (int i = 0; i < result.length; i++) { result[i] = Math.asin(i); } return result; } }
3,@ToString
(1)@ToString 注解在类上, 为类提供 toString() 方法:
- 默认情况下,它会按顺序(以逗号分隔)打印这个类名称以及每个字段。
- 可以这样设置不包含哪些字段:@ToString(exclude = "id") 或者 @ToString(exclude = {"id","name"})
import lombok.Getter; import lombok.Setter; import lombok.ToString; @Getter @Setter @ToString public class User { private String name; private Integer age; }
(2)下面是一个简单的测试样例:
User user = new User(); user.setName("hangge"); user.setAge(123); System.out.println(user.toString());
4,@EqualsAndHashCode
(1)当其注解在类上,为该类提供 hashCode() 和 equals() 方法:
- 默认情况下,它将使用所有非静态,非 transient 字段。
- 可以通过在可选的 exclude 参数中来排除更多字段。
- 也可以通过在 parameter 参数中命名它们来准确指定希望使用哪些字段。
@EqualsAndHashCode public class EqualsAndHashCodeExample { private transient int transientVar = 10; private String name; private double score; /** * 不包含该字段 */ @EqualsAndHashCode.Exclude private Shape shape = new Square(5, 10); private String[] tags; /** * 不包含该字段 */ @EqualsAndHashCode.Exclude private int id; public String getName() { return this.name; } @EqualsAndHashCode(callSuper = true) public static class Square extends Shape { private final int width, height; public Square(int width, int height) { this.width = width; this.height = height; } } public static class Shape { } }
(2)上面编译后会变成如下代码:
import java.util.Arrays; public class EqualsAndHashCodeExample { private transient int transientVar = 10; private String name; private double score; private EqualsAndHashCodeExample.Shape shape = new EqualsAndHashCodeExample.Square(5, 10); private String[] tags; private int id; public EqualsAndHashCodeExample() { } public String getName() { return this.name; } public boolean equals(final Object o) { if (o == this) { return true; } else if (!(o instanceof EqualsAndHashCodeExample)) { return false; } else { EqualsAndHashCodeExample other = (EqualsAndHashCodeExample)o; if (!other.canEqual(this)) { return false; } else { label31: { Object this$name = this.getName(); Object other$name = other.getName(); if (this$name == null) { if (other$name == null) { break label31; } } else if (this$name.equals(other$name)) { break label31; } return false; } if (Double.compare(this.score, other.score) != 0) { return false; } else { return Arrays.deepEquals(this.tags, other.tags); } } } } protected boolean canEqual(final Object other) { return other instanceof EqualsAndHashCodeExample; } public int hashCode() { int PRIME = true; int result = 1; Object $name = this.getName(); int result = result * 59 + ($name == null ? 43 : $name.hashCode()); long $score = Double.doubleToLongBits(this.score); result = result * 59 + (int)($score >>> 32 ^ $score); result = result * 59 + Arrays.deepHashCode(this.tags); return result; } public static class Shape { public Shape() { } } public static class Square extends EqualsAndHashCodeExample.Shape { private final int width; private final int height; public Square(int width, int height) { this.width = width; this.height = height; } public boolean equals(final Object o) { if (o == this) { return true; } else if (!(o instanceof EqualsAndHashCodeExample.Square)) { return false; } else { EqualsAndHashCodeExample.Square other = (EqualsAndHashCodeExample.Square)o; if (!other.canEqual(this)) { return false; } else if (!super.equals(o)) { return false; } else if (this.width != other.width) { return false; } else { return this.height == other.height; } } } protected boolean canEqual(final Object other) { return other instanceof EqualsAndHashCodeExample.Square; } public int hashCode() { int PRIME = true; int result = super.hashCode(); result = result * 59 + this.width; result = result * 59 + this.height; return result; } } }
早年同窗始相知,三载瞬逝情却萌。年少不知愁滋味,犹读红豆生南国。别离方知相思苦,心田红豆根以生。