In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
这篇文章给大家介绍Lombok中@Data如何使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
。
Lombok
先来简单介绍一下 Lombok ,其官方介绍如下:
Project Lombok makes java a spicier language by adding 'handlers' that know how to build and compile simple, boilerplate-free, not-quite-java code.
大致意思是 Lombok 通过增加一些"处理程序",可以让 Java 代码变得简洁、快速。
Lombok 提供了一系列的注解帮助我们简化代码,比如:
注解名称功能@Setter自动添加类中所有属性相关的 set 方法@Getter自动添加类中所有属性相关的 get 方法@Builder使得该类可以通过 builder (建造者模式)构建对象@RequiredArgsConstructor生成一个该类的构造方法,禁止无参构造@ToString重写该类的toString()方法@EqualsAndHashCode重写该类的equals()和hashCode()方法@Data等价于上面的@Setter、@Getter、@RequiredArgsConstructor、@ToString、@EqualsAndHashCode
看起来似乎这些注解都很正常,并且对我们的代码也有一定的优化,那为什么说@Data注解存在坑呢?
@Data注解内部实现
由上面的表格我们可以知道,@Data是包含了@EqualsAndHashCode的功能,那么它究竟是如何重写equals()和hashCode()方法的呢?
我们定义一个类TestA:
@Datapublic class TestA { String oldName;}
我们将其编译后的 class 文件进行反编译:
public class TestA { String oldName; public TestA() { } public String getOldName() { return this.oldName; } public void setOldName(String oldName) { this.oldName = oldName; } public boolean equals(Object o) { // 判断是否是同一个对象 if (o == this) { return true; } // 判断是否是同一个类 else if (!(o instanceof TestA)) { return false; } else { TestA other = (TestA) o; if (!other.canEqual(this)) { return false; } else { // 比较类中的属性(注意这里,只比较了当前类中的属性) Object this$oldName = this.getOldName(); Object other$oldName = other.getOldName(); if (this$oldName == null) { if (other$oldName != null) { return false; } } else if (!this$oldName.equals(other$oldName)) { return false; } return true; } } } protected boolean canEqual(Object other) { return other instanceof TestA; } public int hashCode() { int PRIME = true; int result = 1; Object $oldName = this.getOldName(); int result = result * 59 + ($oldName == null ? 43 : $oldName.hashCode()); return result; } public String toString() { return "TestA(oldName=" + this.getOldName() + ")"; }}
针对其equals()方法,当它进行属性比较时,其实只比较了当前类中的属性。如果你不信的话,我们再来创建一个类TestB,它是TestA的子类:
@Datapublic class TestB extends TestA { private String name; private int age;}
我们将其编译后的 class 文件进行反编译:
public class TestB extends TestA { private String name; private int age; public TestB() { } public String getName() { return this.name; } public int getAge() { return this.age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public boolean equals(Object o) { if (o == this) { return true; } else if (!(o instanceof TestB)) { return false; } else { TestB other = (TestB)o; if (!other.canEqual(this)) { return false; } else { // 注意这里,真的是只比较了当前类中的属性,并没有比较父类中的属性 Object this$name = this.getName(); Object other$name = other.getName(); if (this$name == null) { if (other$name == null) { return this.getAge() == other.getAge(); } } else if (this$name.equals(other$name)) { return this.getAge() == other.getAge(); } return false; } } } protected boolean canEqual(Object other) { return other instanceof TestB; } public int hashCode() { int PRIME = true; int result = 1; Object $name = this.getName(); int result = result * 59 + ($name == null ? 43 : $name.hashCode()); result = result * 59 + this.getAge(); return result; } public String toString() { return "TestB(name=" + this.getName() + ", age=" + this.getAge() + ")"; }}
按照代码的理解,如果两个子类对象,其子类中的属性相同、父类中的属性不同时,利用equals()方法时,依旧会认为这两个对象相同,测试一下:
public static void main(String[] args) { TestB t1 = new TestB(); TestB t2 = new TestB(); t1.setOldName("123"); t2.setOldName("12345"); String name = "1"; t1.name = name; t2.name = name; int age = 1; t1.age = age; t2.age = age; System.out.println(t1.equals(t2)); System.out.println(t2.equals(t1)); System.out.println(t1.hashCode()); System.out.println(t2.hashCode()); System.out.println(t1 == t2); System.out.println(Objects.equals(t1, t2)); }
结果为:
truetrue63736373falsetrue问题总结对于父类是Object且使用了 @EqualsAndHashCode(callSuper = true)注解的类,这个类由 Lombok 生成的 equals()方法只有在两个对象是同一个对象时,才会返回 true ,否则总为 false ,无论它们的属性是否相同。
这个行为在大部分时间是不符合预期的, equals()失去了其意义。即使我们期望 equals()是这样工作的,那么其余的属性比较代码便是累赘,会大幅度降低代码的分支覆盖率。解决方法
用了@Data就不要有继承关系,类似 Kotlin 的做法。
自己重写equals(), Lombok 不会对显式重写的方法进行生成。
显式使用@EqualsAndHashCode(callSuper = true), Lombok 会以显式指定的为准。
关于Lombok中@Data如何使用就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.