Lombok注解-@EqualsAndHashCode

Lombok注解-@EqualsAndHashCode

看该注解的字面意思就是跟equals方法 和 hashCode方法有关的。

我们查看官方文档可以发现:

🍎1. @EqualsAndHashCode以使lombok生成equals(Object other)和hashCode()方法的实现。

🍊2. 它默认使用非静态,非瞬态的属性

🍒3. 可通过参数exclude排除一些属性

🍌4. 可通过参数of指定仅使用哪些属性

🍑5. 它默认仅使用该类中定义的属性且不调用父类的方法

🍍6. 可通过callSuper=true解决上一点问题。让其生成的方法中调用父类的方法。

另外我们看@Data注解的源码注释上写的:

/**
 * Generates getters for all fields, a useful toString method, and hashCode and equals implementations that check
 * all non-transient fields. Will also generate setters for all non-final fields, as well as a constructor.
 * <p>
 * Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.
 * <p>
 * Complete documentation is found at <a href="https://projectlombok.org/features/Data">the project lombok features page for &#64;Data</a>.
 * 
 * @see Getter
 * @see Setter
 * @see RequiredArgsConstructor
 * @see ToString
 * @see EqualsAndHashCode
 * @see lombok.Value
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
	/**
	 * If you specify a static constructor name, then the generated constructor will be private, and
	 * instead a static factory method is created that other classes can use to create instances.
	 * We suggest the name: "of", like so:
	 * 
	 * <pre>
	 *     public @Data(staticConstructor = "of") class Point { final int x, y; }
	 * </pre>
	 * 
	 * Default: No static constructor, instead the normal constructor is public.
	 * 
	 * @return Name of static 'constructor' method to generate (blank = generate a normal constructor).
	 */
	String staticConstructor() default "";
}

注释上写的:
Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.

也就是说@Data等效于@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode注解加一起

所以使用了@Data注解默认就有了@EqualsAndHashCode注解

@EqualsAndHashCode注解中有一个callSuper的属性:

	/**
	 * Call on the superclass's implementations of {@code equals} and {@code hashCode} before calculating for the fields in this class.
	 * <strong>default: false</strong>
	 * 
	 * @return Whether to call the superclass's {@code equals} implementation as part of the generated equals algorithm.
	 */
	boolean callSuper() default false;

这个属性值决定了equals(Object other)和hashCode()方法要不要调用父类的方法,默认为false,也就是不调用。

正常情况下是没有影响的,但是如果继承了父类的情况下就会有问题了:

比如,有多个类有相同的部分属性,把它们定义到父类中,恰好id(数据库主键)也在父类中,那么就会存在部分对象在比较时,它们并不相等,却因为lombok自动生成的equals(Object other) 和 hashCode()方法判定为相等,从而导致出错。

要修复这样的问题也很简单,就是将callSuper属性设置为true即可,怎么设置呢?在使用@Data时多加一个注解:
@EqualsAndHashCode(callSuper = true)

❄️注:如果没有继承任何父类而加了@EqualsAndHashCode(callSuper = true)是会报编译性错误的

posted @ 2020-12-18 15:38  curtin  阅读(438)  评论(0编辑  收藏  举报