为什么我认为 Lombok 应该从 Java 项目中丢弃
2024-09-04 19:54:40
你好,今天的文章解决了一个看似不受欢迎的观点。我相信它会遇到一些阻力。仅仅因为某件事在技术上是可行的,它就不能自动识别它的实用性或适用性。因此,我将试图确认为什么我相信使用它 lombok 可能会对你的代码产生不利影响。
揭开魔力:理解 lombok 项目在深入研究不太流行的细节之前,让我简要解释一下 lombok 库的功能。
project lombok 作为一个库,在编译过程中将代码注入类别,这看起来几乎很神奇。了解其操作和java编译过程至关重要。 java编译主要分为三个阶段(图1):如下图所示:分析与输入、注释处理、分析与生成:
图 1 – 抽象语法树 (ast)
立即学习“Java免费学习笔记(深入);
分析输入: 在这里,编译器将源文件转换为抽象语法树(ast)。仅仅因语法无效而导致错误,而不是因使用错误的类别或方法而导致错误。
注释处理: 在这个阶段,自定义注释处理器验证或生成新的资源(如源文件)。如果生成新的源,可能会触发新的编译周期。
分析生成: 在最后阶段,编译器从 ast 生成字节码,检查损坏引用,验证逻辑流,擦除执行类型,脱糖语法糖。
project lombok 通过注入新的方法、字段或表达式来修改注释处理器 ast。与生成新源的典型处理器不同,lombok 将改变现有类别,这种差异使其能够直接影响字节码的生成。
j2se 1.5 中引入的 annotationprocessor 现有文件无法更改。它只能创建新的文件或字节码。这使得 lombok 因为它们在编译阶段使用,所以实现非常有趣 annotationprocessor 修改现有的 java 类文件。这是 的概述 使用 lombok 编译过程(图 2)。
图2 – lombok的编译过程
龙目岛案件 了解了 lombok 在背后的魔力之后,让我们深入探讨一下我认为它可能对你的代码库有害的原因。增加编译时间 lombok 编译过程中的操作不可避免地会延长,特别是在较大的代码库中,由于需要增加 ast 特别明显的是,管理。
利益错位 lombok 提供各种注释可能会给人一种解决基本编程挑战的错觉。我将讨论我在代码库中经常遇到的一些注释。
-
@builder注释
@data @builder public class course { public enum type { online, onsite; @jsonvalue @override public string tostring() { return super.tostring().tolowercase(); } } private long id; private type type; }
及其用法:
public class coursecreator { public static course createcourse(enrollment enrollment, registration registration) { course.type coursetype = enrollment.getvenue().equals(registration.getvenue()) ? course.type.onsite : course.type.online; return course.builder() .id(enrollment.getid()) .type(coursetype) .build(); } public static void main(string[] args) { registration registration = new registration(); enrollment enrollment = new enrollment(); course course = createcourse(enrollment, registration); system.out.println(course); } }
虽然构建器模式得到了有效的实现,但也引发了创建对象的完整性和有效性的关键问题。
假如我们在构建器中省略了它 .type(),我们将实例化什么类型的课程?
这个代码可以编译,但它让我们怀疑:我们实际上创建了什么类型的课程?这是一个有效的课程实例吗?
course.builder().id(1l).build();
这些担忧表明,开发人员可能会受到注释便利性的影响,并且可能会忽略维护业务逻辑完整性所需的完整域建模。别让 lombok 更重要的是,确保我们的设计与业务需求一致。
考虑调整和实施,以确保任何课程都清晰,并受到商业环境的限制:
@data public class course { private enum type { online, onsite; @jsonvalue @override public string tostring() { return super.tostring().tolowercase(); } } public static course online(long id) { return new course(id, type.online); } public static course onsite(long id) { return new course(id, type.onsite); } private long id; private type type; public boolean isonline() { return type.online.equals(this.type); } public boolean isonsite() { return type.onsite.equals(this.type); } }
通过重新设计:
public class coursemanagement { public static course createappropriatecourse(enrollment enrollment, registration registration) { return enrollment.getvenue().equals(registration.getvenue()) ? course.onsite(enrollment.getid()) : course.online(enrollment.getid()); } public static void main(string[] args) { registration registration = new registration(); enrollment enrollment = new enrollment(); course createdcourse = createappropriatecourse(enrollment, registration); system.out.println(createdcourse); } }
确保了修改后的设计 course 对象的创造是明确而安全的,反映了该领域固有的有限选择,消除了歧义。
另外,通过将军 type 枚举设置为私有,并提供清晰、显式的方法(例如) isonline() 和 isonsite(),我们保证只有公开和有效的操作状态,以保护域的完整性。
通过这种深思熟虑的重组,我们证明了虽然 lombok 这种工具可以显著减少模型代码,但它们不能取代仔细的设计和对该领域的深入理解。它强调应该明智地使用它 lombok,补充而不是掩盖强大的结构实践。这确保了我们代码的优雅不会以牺牲其正确性和清晰度为代价。
-
过度依赖@setter 和@getter
@data public class movie { private string title; private int releaseyear; } // can be replaced with: public record movie(string title, int releaseyear) {}
-
主管@nonnull
为了远离 lombok 的 @nonnull 注释并确保 java 鲁棒本身,java.util.objects 类中的 objects.requirenonnull() 该方法非常有用。
这种方法通过确保对象不是 null 来简化 null 检查,如果是,扔掉 nullpointerexception 并且有明确的消息。这种显式异常抛出机制可以防止潜在的和 null 在运行过程中出现相关错误,从而促进开发周期的早期检测。这是一个例子,展示了如何替换这种方法 lombok 的功能
使用 lombok 的@nonnull:
public class nonnullexample { private student student; public nonnullexample(@nonnull student student) { this.student = student; } }
等效的纯 java 方法:
import java.util.Objects; public class NonNullExample { private Student student; public NonNullExample(Student student) { this.student = Objects.requireNonNull(student, "Student cannot be null"); } }
向本机 java 通过显式空检来增强代码的透明度,有利于代码的维护和理解。
构造函数的灵活性和可重用性 构造函数在软件架构中的交互中起着关键作用。一个设计良好的类别应该有多种结构函数来适应不同的用例,从而提高可重用性和灵活性。假如你的构造函数只是复制字段分配,那么根本的问题不是要编写样板代码;而是要编写样板代码。相反,这就是形成 lombok 不可重用、不灵活的设计风险无法纠正。正确的构造函数设计可以集成和使用各种场景,从而提高代码库的整体健康性和适应性。
样板代码评估:lombok 诱惑与现代 java 功能的对比 lombok 流行主要是因为它降低了样板代码的能力,特别是在传输和数据对象等特定领域。 lombok 必要的代码(例如,自动生成)
getters、setters、equals、hashcode 和 有效减少可见混乱) tostring 这种方法可能会掩盖潜在的陷阱。然而,随着 java 14 中引入的 java records 一种更好的替代方案出现了,它本身就支持不可变数据载体的简单声明。最集成 开发环境 (ide) 还可以通过最少的用户输入自动生成这些样板代码,从而实现 lombok 自动化和传统化 java 提供编码控制之间的平衡。
兼容性问题 project lombok 对底层 java 对版本的依赖带来了很大的兼容性风险。随着 java 抽象语法树的发展 (ast) 结构及其解释可能会发生变化,因此需要不断更新 lombok 确保兼容性。如果有脆弱的依赖关系,就会产生脆弱的依赖关系 lombok 没有同时更新来支持这些变化,升级到更新 java 版本可能会破坏你的构造。依赖非官方或私有 api 由于这些原因,修改类定义进一步加剧了这一问题 api 也许在未来 java 版本受到限制或更改的威胁 lombok 长期生存能力。java标准 只使用标准 java 使用编译器选项的工具构建项目时,使用 lombok 它可能会导致复杂性。例如,如果使用代码 lombok 生成的 getter 和 setter,则直接使用
javac 而不是编译 lombok 预处理可能会导致错误,缺乏指示方法。尽管有些人可能会这么想 lombok 注入代码的能力是一项聪明的“技能”,但批判性地评估相关风险和替代方案至关重要。在编译过程中,java的注释处理规范并不正式支持现有类别的修改。依赖于这些非官方技术, lombok 接受未来很容易 java 这些更新可能会破坏或禁用其功能。
最后,这些考虑因素强调不仅要评估 lombok 其他工具直接好处的重要性也应评估其可维护性、兼容性和与 java 长期影响标准的一致性。随着 java 对稳定性和标准化功能的依赖越来越重要,以确保软件项目的可持续性和可靠性。结论 lombok 似乎是 java 方便开发,但它会 java 代码转换为特定于域的版本,我喜欢称之为
“lombok java".必须认识到过度依赖 lombok 可能会掩盖 java 本质上,代码可能不够强大,而且没有 lombok 在这种情况下更难管理。
若过度依赖 lombok 这是管理代码库的解决方案,所以是时候重新评估底层结构和实践了。 java 它的真正优势在于它的清晰度和结构,而不是外部库提供的快捷方式。
如果有机会,我会选择放弃我的项目 lombok。
这就是为什么我认为这就是为什么 Lombok 应该从 Java 更多关于图灵教育的其他相关文章,请关注项目中丢弃的细节!