Lombok要点 偏执的太偏执、 2023-10-18 22:11 85阅读 0赞 **目录** 1.局部变量类型推断:val 和 var 2.@NonNull 3.更简洁的数据类 3.1. @Getter 和 @Setter 3.2. @AllArgsConstructor 3.3. @ToString 3.4. @EqualsAndHashCode 3.5. @Data 4. 使用 @Buidler 创建对象 5.日志 6.Lombok给你控制权 7.写得更少,做得更多 8. 延展阅读 -------------------- 和其他语言相比, Java经常因为不必要的冗长被批评。 Lombok提供了一系列注解用以在后台生成模板代码,将其从你的类中删除,从而有助于保持你的代码整洁。较少的模板意味着更简洁的代码,更易于阅读和维护。在本文中,我将涉及我经常使用的 Lombok功能,并想你展示如何使用他们生产更清晰、更简洁的代码。 ### **1.局部变量类型推断:val 和 var** ### 许多语言通过查看等号右侧的表达式来推断局部变量类型。尽管现在 Java10+已经支持这种功能,但在之前的版本中没有 Lombok的帮助就无法实现。下面的代码段展示了如何显式指定局部类型: final Map<String, Integer> map = new HashMap<>(); map.put("Joe", 21); 在 Lombok中,我们可以通过使用 val来缩短它,如下所示: val valMap = new HashMap<String, Integer>(); valMap.put("Sam", 30); 注意, val在背后创建了一个 final且不可变的变量。如果你需要一个可变本地变量,可以使用 var。 ### **2.@NonNull** ### 对方法参数进行 null检查通常不是一个坏主意,特别是如果该方法形成的 API被其他开发者使用。虽然这些检查很简单,但是他们可能变得冗长,特别是当你有多个参数时。如下所示,额外的代码无助于可读性,并且可能从方法的主要目的分散注意力。 public void nonNullDemo(Employee employee, Account account) { if(employee == null) { throw new IllegalArgumentException("Employee is marked @NonNull but is null"); } if(account == null) { throw new IllegalArgumentException("Account is marked @NonNull but is null"); } // do stuff } 理想情况下,你需要 null检查——没有干扰的那种。这就是 @NonNull发挥作用的地方。通过用 @NonNull标记参数, Lombok替你为该参数生成 null检查。你的方法突然变得更加简洁,但没有丢失那些安全性的 null检查。 public void nonNullDemo(@NonNull Employee employee, @NonNull Account account) { // just do stuff } 默认情况下, Lombok会抛出 NullPointerException,如果你愿意,可以配置 Lombok抛出 IllegalArgumentException。我个人更喜欢 IllegalArgumentException,因为我认为它更适合于对参数检查。 ### **3.更简洁的数据类** ### 数据类是 Lombok真正有助于减少模板代码的领域。在查看该选项前,思考一下我们经常需要处理的模板种类。数据类通常包括以下一种或全部: 构造函数(有或没有参数) 私有成员变量的 getter 方法 私有非 final 成员变量的 setter 方法 帮助记录日志的 toString 方法 equals 和 hashCode(处理相等/集合) 可以通过 IDE 生成以上内容,因此问题不在于编写他们花费的时间。问题是带有少量成员变量的简单类很快会变得非常冗长。让我们看看 Lombok如何通过处理上述的每一项来减少混乱。 #### **3.1. @Getter 和 @Setter** #### 想想下面的 Car类。当生成 getter和 setter时,我们会得到接近 50 行代码来描述一个包含 5 个成员变量的类。 public class Car { private String make; private String model; private String bodyType; private int yearOfManufacture; private int cubicCapacity; public String getMake() { return make; } public void setMake(String make) { this.make = make; } public String getModel() { return model; } public void setModel(String model) { this.model = model; } public String getBodyType() { return bodyType; } public void setBodyType(String bodyType) { this.bodyType = bodyType; } public int getYearOfManufacture() { return yearOfManufacture; } public void setYearOfManufacture(int yearOfManufacture) { this.yearOfManufacture = yearOfManufacture; } public int getCubicCapacity() { return cubicCapacity; } public void setCubicCapacity(int cubicCapacity) { this.cubicCapacity = cubicCapacity; } } Lombok可以替你生成 getter和 setter模板。通过对每个成员变量使用 @Getter和 @Setter注解,你最终得到一个等效的类,如下所示: 1. public class Car { @Getter @Setter private String make; @Getter @Setter private String model; @Getter @Setter private String bodyType; @Getter @Setter private int yearOfManufacture; @Getter @Setter private int cubicCapacity; } 注意,你可以在非 final成员变量上只使用 @Setter。在 final成员变量上使用它将导致编译错误。 如果你需要为每个成员变量生成 getter和 setter,你也可以在类级别使用 @Getter和 @Setter,如下所示。 @Getter @Setter public class Car { private String make; private String model; private String bodyType; private int yearOfManufacture; private int cubicCapacity; } #### **3.2. @AllArgsConstructor** #### 数据类通常包含一个构造函数,它为每个成员变量接受参数。IDE 为 Car生成的构造函数如下所示: public class Car { @Getter @Setter private String make; @Getter @Setter private String model; @Getter @Setter private String bodyType; @Getter @Setter private int yearOfManufacture; @Getter @Setter private int cubicCapacity; public Car(String make, String model, String bodyType, int yearOfManufacture, int cubicCapacity) { super(); this.make = make; this.model = model; this.bodyType = bodyType; this.yearOfManufacture = yearOfManufacture; this.cubicCapacity = cubicCapacity; } } 我们可以使用 @AllArgsConstructor注解实现同样功能。 @Getter和 @Setter、 @AllArgsConstructor减少模板,保持类更干净且更简洁。 @AllArgsConstructor public class Car { @Getter @Setter private String make; @Getter @Setter private String model; @Getter @Setter private String bodyType; @Getter @Setter private int yearOfManufacture; @Getter @Setter private int cubicCapacity; } 还有其他选项用于生成构造函数。 @RequiredArgsConstructor将创建带有每个 final成员变量参数的构造函数, @NoArgsConstructor将创建没有参数的构造函数。 #### **3.3. @ToString** #### 在你的数据类上覆盖 toString方法是有助于记录日志的良好实践。IDE 为 Car类生成的 toString方法如下所示: @AllArgsConstructor public class Car { @Getter @Setter private String make; @Getter @Setter private String model; @Getter @Setter private String bodyType; @Getter @Setter private int yearOfManufacture; @Getter @Setter private int cubicCapacity; @Override public String toString() { return "Car [make=" + make + ", model=" + model + ", bodyType=" + bodyType + ", yearOfManufacture=" + yearOfManufacture + ", cubicCapacity=" + cubicCapacity + "]"; } } 我们可以使用 ToString注解废除这个,如下所示: @ToString @AllArgsConstructor public class Car { @Getter @Setter private String make; @Getter @Setter private String model; @Getter @Setter private String bodyType; @Getter @Setter private int yearOfManufacture; @Getter @Setter private int cubicCapacity; } 默认情况下, Lombok生成包含所有成员变量的 toString方法。可以通过 exclude属性 @ToString(exclude=\{"someField"\},"someOtherField"\}) 覆盖行为将某些成员变量排除。 #### **3.4. @EqualsAndHashCode** #### 如果你正在将你的数据类和任何类型的对象比较,则需要覆盖 equals和 hashCode 方法。对象的相等是基于业务规则定义的。举个例子,在 Car类中,如果两个对象有相同的 make、 model和 bodyType,我可能认为他们是相等的。如果我使用 IDE 生成 equals方法检查 make、 model和 bodyType,它看起来会是这样: @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Car other = (Car) obj; if (bodyType == null) { if (other.bodyType != null) return false; } else if (!bodyType.equals(other.bodyType)) return false; if (make == null) { if (other.make != null) return false; } else if (!make.equals(other.make)) return false; if (model == null) { if (other.model != null) return false; } else if (!model.equals(other.model)) return false; return true; } 等价的 hashCode实现如下所示: @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((bodyType == null) ? 0 : bodyType.hashCode()); result = prime * result + ((make == null) ? 0 : make.hashCode()); result = prime * result + ((model == null) ? 0 : model.hashCode()); return result; } 虽然 IDE 处理了繁重的工作,但我们在类中仍然有大量的模板代码。 Lombok允许我们使用 @EqualsAndHashCode类注解实现相同的功能,如下所示: @ToString @AllArgsConstructor @EqualsAndHashCode(exclude = { "yearOfManufacture", "cubicCapacity" }) public class Car { @Getter @Setter private String make; @Getter @Setter private String model; @Getter @Setter private String bodyType; @Getter @Setter private int yearOfManufacture; @Getter @Setter private int cubicCapacity; } 默认情况下, @EqualsAndHashCode会创建包含所有成员变量的 equals和 hashCode方法。 exclude选项可用于通知 Lombok排除某些成员变量。在上面的代码片段中。我已经从生成的 equals和 hashCode方法中排除了 yearOfManuFacture 和 cubicCapacity。 #### **3.5. @Data** #### 如果你想使数据类尽可能精简,可以使用 @Data注解。 @Data 是 @Getter、 @Setter、 @ToString、 @EqualsAndHashCode 和 @RequiredArgsConstructor 的快捷方式。 @ToString @RequiredArgsConstructor @EqualsAndHashCode(exclude = \{ "yearOfManufacture", "cubicCapacity" \}) public class Car \{ @Getter @Setter private String make; @Getter @Setter private String model; @Getter @Setter private String bodyType; @Getter @Setter private int yearOfManufacture; @Getter @Setter private int cubicCapacity; \} 通过使用 @Data,我们可以将上面的类精简如下: @Data public class Car \{ private String make; private String model; private String bodyType; private int yearOfManufacture; private int cubicCapacity; \} 1. ### **4. 使用 @Buidler 创建对象** ### 建造者设计模式描述了一种灵活的创建对象的方式。 Lombok可以帮你轻松的实现该模式。看一个使用简单 Car类的示例。假设我们希望可以创建各种 Car对象,但我们希望在创建时设置的属性具有灵活性。 @AllArgsConstructor public class Car { private String make; private String model; private String bodyType; private int yearOfManufacture; private int cubicCapacity; private List<LocalDate> serviceDate; } 假设我们要创建一个 Car,但只想设置 make和 model。在 Car上使用标准的全参数构造函数意味着我们只提供 make和 model并设置其他参数为 null。 Car2 car2 = new Car2("Ford", "Mustang", null, null, null, null); 这可行但并不理想,我们必须为我们不感兴趣的参数传递 null。我们可以创建一个只接受 make和 model的构造函数来避开这个问题。这是一个合理的解决方法,但不够灵活。如果我们有许多不同的字段排列,我们可以用什么来创建一个新 Car?最终我们得到了一堆不同的构造函数,代表了我们可以实例化 Car的所有可能方式。 解决该问题的一种干净、灵活的方式是使用建造者模式。 Lombok通过 @Builder 注解帮你实现建造者模式。当你使用 @Builder注解 Car类时, Lombok会执行以下操作: * 添加一个私有构造函数到 Car * 创建一个静态的 CarBuilder类 * 在 CarBuilder中为 Car中的每个成员创建一个 setter风格方法。 * 在 CarBuilder中添加创建 Car的新实例的建造方法。 CarBuilder上的每个 setter风格方法返回自身的实例( CarBuilder)。这允许你进行方法链式调用并为对象创建提供流畅的 API。让我们看看它如何使用。 Car muscleCar = Car.builder().make("Ford") .model("mustang") .bodyType("coupe") .build(); 现在只使用 make和 model创建 Car比之前更简洁了。只需在 Car上简单的调用生成的 builder方法获取 CarBuilder实例,然后调用任何我们感兴趣的 setter风格方法。最后,调用 build创建 Car的新实例。 另一个值得一提的方便的注解是 @Singular。默认情况下,Lombok 为集合创建使用集合参数的标准的 setter 风格方法。在下面的例子中,我们创建了新的 Car并设置了服务日期列表。 Car muscleCar = Car.builder().make("Ford") .model("mustang") .serviceDate(Arrays.asList(LocalDate.of(2016, 5, 4))) .build(); 向集合成员变量添加 @Singular将提供一个额外的方法,允许你向集合添加单个项。 @Builder public class Car { private String make; private String model; private String bodyType; private int yearOfManufacture; private int cubicCapacity; @Singular private List<LocalDate> serviceDate; } 现在我们可以添加单个服务日期,如下所示: Car muscleCar3 = Car.builder() .make("Ford") .model("mustang") .serviceDate(LocalDate.of(2016, 5, 4)) .build(); 这是一个有助于在创建对象期间处理集合时保持代码简洁的快捷方法。 ### **5.日志** ### Lombok另一个伟大的功能是日志记录器。如果没有 Lombok,要实例化标准的 SLF4J日志记录器,通常会有以下内容: public class SomeService { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class) public void doStuff(){ log.debug("doing stuff...."); } } 这些日志记录器很沉重,并为每个需要日志记录的类添加了不必要的混乱。值得庆幸的是 Lombok提供了一个为你创建日志记录器的注解。你要做的所有事情就是在类上添加注解,这样就可以了。 @Slf4j public class SomeService { public void doStuff(){ log.debug("doing stuff...."); } } 我在这里使用了 @SLF4J注解,但 Lombok能为几乎所有通用 Java日志框架生成日志记录器。有关更多日志记录器的选项,请参阅文档。 ### **6.Lombok给你控制权** ### 我非常喜欢 Lombok的一点是它的不侵入性。。如果你决定在使用如 @Getter、 @Setter 或 @ToString时也想要自己的方法实现,你的方法将总是优先于 Lombok。它允许你在大多数时间使用 Lombok,但在你需要的时候仍有控制权。 ### **7.写得更少,做得更多** ### 在过去的 4 到 5 年里,我几乎在每个项目中都使用了 Lombok。我喜欢它,因为它减少了杂乱,最终得到了更干净、更简洁、更易阅读的代码。它不一定为你节省大量时间,因为它生成的代码可以由 IDE 自动生成。话虽如此,我认为更干净的代码的好处不仅仅是将其添加到 Java堆栈中。 ### **8. 延展阅读** ### 我已经介绍了我经常使用的 Lombok功能,但还有很多我没有讲到。如果你喜欢目前为止所看到的,并希望了解更多,请继续阅读 Lombok 文档。
相关 Lombok要点 目录 1.局部变量类型推断:val 和 var 2.@NonNull 3.更简洁的数据类 3.1. @Getter 和 @Setter 3.2. @AllArgsCo 偏执的太偏执、/ 2023年10月18日 22:11/ 0 赞/ 86 阅读
相关 lombok 为什么需要lombok Java项目中,充斥着太多不友好的代码:POJO的getter/setter/toString;这些样板代码既没有技术含量,写起来又比较麻烦,又影响 绝地灬酷狼/ 2022年12月11日 02:28/ 0 赞/ 117 阅读
相关 lombok 转自:http://blog.csdn.net/mlinge/article/details/51340362 lombok是什么 lombok 是通过提供简单注 傷城~/ 2022年07月12日 06:56/ 0 赞/ 188 阅读
相关 lombok 转自:http://blog.csdn.net/mlinge/article/details/51340362 lombok是什么 lombok 是通过提供简单注 - 日理万妓/ 2022年07月12日 06:56/ 0 赞/ 187 阅读
相关 Lombok 【问题描述】 长假回来上班后的第一天,开发环境竟然出问题了。代码中所有的getter和setter方法都报错,显示各个实体类中没有提供对应的get/set方法。 ゝ一世哀愁。/ 2022年06月07日 03:44/ 0 赞/ 195 阅读
相关 Lombok https://www.jianshu.com/p/365ea41b3573 Lombok简介\\\ Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些 骑猪看日落/ 2022年06月02日 00:45/ 0 赞/ 245 阅读
相关 Lombok Lombok简介 > Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对 桃扇骨/ 2022年05月22日 00:23/ 0 赞/ 193 阅读
相关 lombok lombok简介 lombok是暑假来到公司实习的时候发现的一个非常好用的小工具,刚见到的时候就感觉非常惊艳,有一种相见恨晚的感觉,用了一段时间之后感觉的确挺不错,所以特 阳光穿透心脏的1/2处/ 2022年05月17日 04:46/ 0 赞/ 190 阅读
相关 Lombok 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MOTUI/article/details/79012846 Lombok 港控/mmm°/ 2022年05月14日 16:45/ 0 赞/ 192 阅读
相关 Lombok 概述 Lombok 提供了一些注解来帮助我们简化消除一些必须有但显得臃肿的 java 代码,如 getting 和 setting,它是通过编译时字节码修改完成,性 素颜马尾好姑娘i/ 2021年09月10日 06:08/ 0 赞/ 368 阅读
还没有评论,来说两句吧...