462

如果您不知道Project Lombok可以帮助解决 Java 的一些烦恼,例如生成带有注释的 getter 和 setter,甚至像使用 @Data 生成简单的 JavaBean。它真的可以帮助我,尤其是在 50 个不同的事件对象中,您有多达 7 个不同的字段需要用 getter 构建和隐藏。我可以用这个删除近一千行代码。

但是,我担心从长远来看,这将是一个令人遗憾的决定。当我提到它时, Flamewars 将在##Java Freenode频道中爆发,提供代码片段会使可能的帮助者感到困惑,人们会抱怨缺少 JavaDoc,未来的提交者可能无论如何都会将其全部删除。我真的很喜欢积极的一面,但我担心消极的一面。

所以:在任何项目上使用 Lombok 是否安全,无论大小?积极的影响是否值得消极的影响?

4

15 回答 15

920

今天刚开始使用 Lombok。到目前为止,我喜欢它,但我没有看到提到的一个缺点是重构支持。

如果您有一个用 注释的类@Data,它将根据字段名称为您生成 getter 和 setter。如果您在另一个类中使用其中一个 getter,然后确定该字段命名不当,它将找不到这些 getter 和 setter 的用法,并用新名称替换旧名称。

我想这必须通过 IDE 插件而不是通过 Lombok 来完成。

更新(2013 年 1 月 22 日)
在使用 Lombok 3 个月后,我仍然推荐它用于大多数项目。但是,我确实发现了另一个类似于上面列出的缺点。

如果你有一个类,假设它有 2 个成员,都用,say和MyCompoundObject.java注释,当你从另一个类调用时,不可能知道它是委托给还是因为你不能再跳转到 IDE 中的源代码。@DelegatemyWidgetsmyGadgetsmyCompoundObject.getThingies()WidgetGadget

使用 Eclipse“生成委托方法...”为您提供相同的功能,同样快速并提供源代码跳转。不利的一面是它会使您的源代码与样板代码混淆,从而将注意力从重要的东西上移开。

更新 2(2013 年 2 月 26 日)
5 个月后,我们仍在使用 Lombok,但我还有其他一些烦恼。当您尝试熟悉新代码时,缺少已声明的 getter 和 setter 有时会很烦人。

例如,如果我看到一个被调用的方法,getDynamicCols()但我不知道它是关于什么的,那么我有一些额外的障碍需要跳过来确定这个方法的用途。有些障碍是 Lombok,有些是缺少 Lombok 智能插件。障碍包括:

  • 缺乏 JavaDocs。如果我对该字段进行 javadoc,我希望 getter 和 setter 将通过 Lombok 编译步骤继承该 javadoc。
  • 跳转到方法定义会将我跳转到类,但不会跳转到生成 getter 的属性。这是一个插件问题。
  • 显然,除非您生成或编码该方法,否则您无法在 getter/setter 中设置断点。
  • 注意:此参考搜索不是我最初认为的问题。您确实需要使用启用大纲视图的透视图。对于大多数开发人员来说不是问题。我的问题是我正在使用过滤我的Outline视图的 Mylyn,所以我没有看到这些方法。 缺乏参考文献搜索。如果我想查看谁在调用getDynamicCols(args...),我必须生成或编码 setter 以便能够搜索引用。

更新 3(2013 年 3 月 7 日)
我猜想学习在 Eclipse 中使用各种做事方式。您实际上可以在 Lombok 生成的方法上设置条件断点 (BP)。使用Outline视图,您可以右键单击方法来Toggle Method Breakpoint. 然后当你点击BP时,你可以使用调试Variables视图查看生成的方法命名参数(通常与字段名称相同),最后使用Breakpoints视图右键单击BP并选择Breakpoint Properties...添加条件。好的。

更新 4(2013 年 8 月 16 日)
当您在 Maven pom.xml 中更新 Lombok 依赖项时,Netbeans 不喜欢它。该项目仍在编译,但文件被标记为存在编译错误,因为它看不到 Lombok 正在创建的方法。清除 Netbeans 缓存可解决此问题。不确定是否有像 Eclipse 那样的“清理项目”选项。小问题,但想让它知道。

更新 5(2014 年 1 月 17 日)
Lombok 并不总是与 Groovy 配合得很好,或者至少groovy-eclipse-compiler. 您可能必须降级编译器的版本。 Maven Groovy 和 Java + Lombok

更新 6(2014 年 6 月 26 日)
警告。Lombok 有点让人上瘾,如果你在一个项目中工作,由于某种原因你不能使用它,它会惹恼你。根本不使用它可能会更好。

更新 7(2014 年 7 月 23 日)
这是一个有趣的更新,因为它直接解决了 OP 询问的采用 Lombok的安全性。

从 v1.14 开始,@Delegate注释已降级为实验状态。详细信息记录在他们的网站上(Lombok Delegate Docs)。

问题是,如果您使用此功能,您的退出选项是有限的。我将选项视为:

  • 手动删除@Delegate注释并生成/手动编码委托代码。如果您在注释中使用属性,这会有点困难。
  • Delombok 包含@Delegate注释的文件,并可能添加回您想要的注释。
  • 永远不要更新 Lombok 或维护分叉(或使用体验功能)。
  • Delombok 你的整个项目并停止使用 Lombok。

据我所知,Delombok 没有删除注释子集的选项;至少对于单个文件的上下文,它是全部或全部。我开了一张票,要求使用 Delombok 标志来请求此功能,但我不希望在不久的将来会出现这种情况。

更新 8(2014 年 10 月 20 日)
如果您愿意,Groovy 提供了 Lombok 的大部分相同优势,以及大量其他功能,包括@Delegate。如果您认为您很难将这个想法推销给当权者,请查看@CompileStatic@TypeChecked注释,看看这是否有助于您的事业。事实上,Groovy 2.0 版本的主要焦点是静态安全

更新 9(2015 年 9 月 1 日)
Lombok 仍在积极维护和增强,这预示着采用的安全级别。@Builder注释是我最喜欢的新功能之一

更新 10(2015 年 11 月 17 日)
这似乎与 OP 的问题没有直接关系,但值得分享。如果您正在寻找工具来帮助您减少编写的样板代码量,您还可以查看Google Auto - 特别是AutoValue。如果您查看他们的幻灯片,将 Lombok 列为他们试图解决的问题的可能解决方案。他们为龙目岛列出的缺点是:

  • 插入的代码是不可见的(你不能“看到”它生成的方法)[ed note - 实际上你可以,但它只需要一个反编译器]
  • 编译器黑客是非标准且脆弱的
  • “在我们看来,您的代码不再是真正的 Java”

我不确定我是否同意他们的评价。鉴于幻灯片中记录的 AutoValue 的缺点,我将坚持使用 Lombok(如果 Groovy 不是一个选项)。

更新 11(2016 年 2 月 8 日)
我发现Spring Roo有一些类似的注释。我有点惊讶地发现 Roo 仍然是一个东西,并且为注释查找文档有点粗糙。移除看起来也不像 de-lombok 那样容易。龙目岛似乎是更安全的选择。

更新 12(2016 年 2 月 17 日)
在尝试为我目前正在进行的项目引入 Lombok 的安全性提出理由时,我发现了一块添加了v1.14-配置系统的黄金!这意味着您可以配置项目以禁止您的团队认为不安全或不受欢迎的某些功能。更好的是,它还可以创建具有不同设置的目录特定配置。这太棒了。

更新 13(2016 年 10 月 4 日)
如果这种事情对您很重要,Oliver Gierke认为将 Lombok 添加到 Spring Data Rest是安全的。

更新 14(2017 年 9 月 26 日)正如@gavenkoa在对 OPs 问题的评论中
所指出的, JDK9 编译器支持尚不可用(问题 #985)。听起来这对 Lombok 团队来说并不是一个容易解决的问题。

更新 15(2018 年 3 月 26 日)
Lombok 更改日志从 v1.16.20 开始显示“现在可以在 JDK1.9 上编译 lombok ”,即使#985仍处于打开状态。

然而,为适应 JDK9 所做的更改需要进行一些重大更改;所有这些都与配置默认值的更改隔离。他们引入了重大更改有点令人担忧,但该版本仅增加了“增量”版本号(从 v1.16.18 到 v1.16.20)。由于这篇文章是关于安全的,如果你有一个yarn/npm类似的构建系统自动升级到最新的增量版本,你可能会被粗鲁地唤醒。

更新 16(2019 年 1 月 9 日)

据我所知,似乎JDK9 问题已经解决,Lombok 可以与 JDK10 甚至 JDK11 一起使用。

尽管从安全方面考虑,但我注意到的一件事是,从 v1.18.2 到 v1.18.4 的更改日志将两项列为BREAKING CHANGE!? 我不确定在 semver“补丁”更新中如何发生重大变化。如果您使用自动更新补丁版本的工具,可能会出现问题。

更新 17(21 年 3 月 17 日)

Lombok 开发人员和 OpenJDK 开发人员之间围绕 JDK 16 发生了一些戏剧性 的事件。JDK 开发人员认为,Lombok 正在通过 JDK 团队希望关闭的漏洞利用未发布的 JDK 内部结构,但出于各种原因故意保持开放状态。

他们表达了他们的担忧(关于龙目岛的安全):

只要客户端应用程序明确允许,所有对内部的访问都将像以前一样保持可用,并承认它有意承担这可能带来的任何维护(或安全)问题。

虽然 Lombok 可能认为他们在欺骗 OpenJDK,但他们所做的只是宣布他们打算欺骗自己的用户。

很快就会有一天,Lombok 将无法围绕 JDK 的安全限制找到任何更具创造性的解决方案。即使他们这样做了,在您的项目中使用 Lombok 的安全性也可能存在问题。

于 2012-10-09T20:30:53.403 回答
187

听起来您已经决定 Project Lombok 为您提议的新项目提供了显着的技术优势。(从一开始就明确一点,我对龙目岛项目没有特别的看法,不管是哪种方式。)

在某些项目(开源或其他方式)中使用 Project Lombok(或任何其他改变游戏规则的技术)之前,您需要确保项目利益相关者同意这一点。这包括开发人员和任何重要的用户(例如正式或非正式的赞助商)。

你提到了这些潜在的问题:

当我提到它时,Flamewars 会在##Java Freenode 频道中爆发,

简单的。忽略/不参与火焰战争,或者干脆不提龙目岛。

提供代码片段会混淆可能的帮助者,

如果项目策略是使用 Lombok,那么可能的帮助者将需要习惯它。

人们会抱怨缺少 JavaDoc,

那是他们的问题。没有人会试图将其组织的源代码/文档规则严格地应用于第三方开源软件。项目团队应该可以自由设置适合所使用技术的项目源代码/文档标准。

跟进- Lombok 开发人员认识到不为合成的 getter 和 setter 方法生成 javadoc 注释是一个问题。如果这是您项目的主要问题,那么另一种方法是创建并提交 Lombok 补丁来解决这个问题。 )

并且未来的提交者可能只是将其全部删除。

那不开!如果商定的项目策略是使用 Lombok,那么无偿取消 Lombok 代码的提交者应受到惩罚,并在必要时撤销其提交权。

当然,这假设您已经获得了利益相关者的支持……包括开发人员。它假设你准备好为你的事业辩护,并适当地处理不可避免的反对声音。

于 2010-10-04T00:34:02.063 回答
122

继续使用 Lombok,如有必要,您可以在之后“delombok”您的代码http://projectlombok.org/features/delombok.html

于 2010-10-04T07:24:41.787 回答
79

就个人而言(因此主观上),我发现与 IDE/自己的复杂方法(例如 hashcode 和 equals)实现相比,使用 Lombok 使我的代码更能表达我想要实现的目标。

使用时

@EqualsAndHashCode(callSuper = false, of = { "field1", "field2", "field3" })

与任何 IDE/自己的实现相比,保持 Equals 和 HashCode 一致并跟踪评估哪些字段要容易得多。当您仍在定期添加/删除字段时尤其如此。

注释及其参数也是如此@ToString,它们清楚地传达了有关包含/排除字段、getter 或字段访问的使用以及是否调用的所需行为super.toString()

@Getter再次通过使用or注释整个类@Setter(AccessLevel.NONE)(并可选地覆盖任何不同的方法),可以立即清楚哪些方法可用于字段。

福利还在继续。。

在我看来,这不是关于减少代码,而是关于清楚地传达你想要实现的目标,而不是必须从 Javadoc 或实现中弄清楚。减少的代码只是更容易发现任何不同的方法实现。

于 2010-10-04T08:06:16.790 回答
28

我阅读了一些关于 Lombok 的意见,实际上我在一些项目中使用它。

嗯,在第一次接触龙目岛时,我印象很差。几个星期后,我开始喜欢它。但是几个月后,我发现了很多使用它的小问题。所以,我对龙目岛的最终印象并不是那么积极。

我这样想的理由:

  • IDE 插件依赖。Lombok 的 IDE 支持是通过插件实现的。即使在大多数情况下工作得很好,您也始终是这个插件的人质,将在未来的 IDE版本甚至语言版本中进行维护(Java 10+ 将加速该语言的开发)。例如,我尝试从 Intellij IDEA 2017.3 更新到 2018.1,但我不能这样做,因为实际的 lombok 插件版本存在一些问题,我需要等待插件更新......如果你这样做,这也是一个问题想使用没有任何 Lombok 插件支持的更多替代 IDE。
  • “查找用途”问题。. 使用 Lombok,您看不到生成的 getter、setter、构造函数、构建器方法等。因此,如果您打算找出 IDE 在您的项目中使用这些方法的位置,您不能只看对于拥有此隐藏方法的类。
  • 如此简单以至于开发人员不关心打破封装。我知道这不是龙目岛的真正问题。但我看到开发人员更倾向于不再控制哪些方法需要可见或不可见。因此,很多时候他们只是复制和粘贴@Getter @Setter @Builder @AllArgsConstructor @NoArgsConstructor注释块,而不考虑类真正需要公开哪些方法。
  • 建设者痴迷©。我发明了这个名字(下车,Martin Fowler)。开个玩笑,一个 Builder 很容易创建,即使一个类只有两个参数,开发人员更喜欢使用@Builder而不是构造函数或静态构造函数方法。有时他们甚至尝试在 lombok Builder 中创建一个 Builder,从而产生奇怪的情况,例如MyClass.builder().name("Name").build().create().
  • 重构时的障碍。例如,如果您正在使用 a@AllArgsConstructor并且需要在构造函数上添加一个额外的参数,则 IDE 无法帮助您在实例化该类的所有位置(主要是测试)中添加这个额外的参数。
  • 用具体方法混合龙目岛。您不能在所有场景中都使用 Lombok 来创建 getter/setter/etc。因此,您将看到这两种方法混合在您的代码中。一段时间后你会习惯这一点,但感觉就像是对语言的破解。

就像另一个答案所说,如果您对 Java 的冗长感到愤怒并使用 Lombok 来处理它,请尝试使用 Kotlin。

于 2018-03-23T16:08:06.093 回答
26

龙目岛很棒,但是...

Lombok 打破了注释处理的规则,因为它不会生成新的源文件。这意味着如果他们期望 getter/setter 或其他任何东西存在,它就不能与另一个注释处理器一起使用。

注释处理在一系列轮次中运行。在每一轮中,每个人都可以轮流奔跑。如果在回合完成后发现任何新的 java 文件,则开始另一回合。这样,如果注释处理器只生成新文件,它们的顺序就无关紧要了。由于 lombok 不会生成任何新文件,因此不会启动新的轮次,因此一些依赖 lombok 代码的 AP 不会按预期运行。在使用 mapstruct 时,这对我来说是一个巨大的痛苦来源,而 delombok-ing 并不是一个有用的选项,因为它会破坏日志中的行号。

我最终破解了一个构建脚本,可以同时使用 lombok 和 mapstruct。但我想放弃龙目岛,因为它是多么的 hacky——至少在这个项目中。我一直在其他东西中使用龙目岛。更新到专门的 mapstruct+lombok:这两个库现在可以开箱即用。不过,对于其他注释处理器,这个问题仍然存在。

于 2016-07-24T16:25:03.613 回答
22

也存在长期维护风险。首先,我建议阅读 Lombok 的实际工作原理,例如这里的开发人员提供的一些答案。

官方网站还包含一个缺点列表,包括 Reinier Zwitserloot 的这句话:

这是一个彻头彻尾的黑客攻击。使用非公共 API。假定的强制转换(知道在 javac 中运行的注释处理器将获得 JavacAnnotationProcessor 的实例,它是 AnnotationProcessor(一个接口)的内部实现,因此恰好有几个额外的方法用于获取实时 AST) .

在 Eclipse 上,它可以说更糟(但更健壮)——Java 代理用于将代码注入 Eclipse 语法和解析器类,这当然是完全非公共 API 并且完全不受限制。

如果你可以用标准 API 做 lombok 做的事情,我会那样做,但你不能。尽管如此,我还是为在 java 1.6 上运行的 eclipse v3.5 开发了 eclipse 插件,并且没有做任何更改,它也可以在运行在 java 1.5 上的 eclipse v3.4 上运行,所以它并不完全脆弱。

总而言之,虽然 Lombok 可能会为您节省一些开发时间,但如果有非向后兼容的 javac 更新(例如漏洞缓解),Lombok 可能会让您卡在旧版本的 Java 中,而开发人员则争先恐后地更新他们对这些的使用内部 API。这是否是一个严重的风险显然取决于项目。

于 2016-06-02T15:40:45.147 回答
15

一年来,我几乎在所有项目中都使用了 Lombok,但不幸的是删除了它。一开始这是一种非常干净的开发方式,但是为新团队成员设置开发环境并不是很容易和直接。当它变得头疼时,我就把它拿掉了。但这是一项很好的工作,需要更简单的设置。

于 2012-07-02T12:59:35.753 回答
15

我知道我迟到了,但我无法抗拒诱惑:任何喜欢 Lombok 的人也应该看看 Scala。您在 Lombok 中发现的许多好主意都是 Scala 语言的一部分。

关于您的问题:让您的开发人员尝试 Lombok 肯定比 Scala 更容易。试一试,如果他们喜欢,试试 Scala。

就像免责声明一样:我也喜欢 Java!

于 2013-08-16T19:20:07.633 回答
13

当我向我的团队展示这个项目时,他们的热情很高,所以我认为你不应该害怕团队的反应。

  • 就投资回报率而言,它可以快速集成,并且不需要更改其基本形式的代码。(只需向您的班级添加一个注释)

  • 最后,如果你改变主意,你可以运行 unlombok,或者让你的 IDE 创建这些 setter、getter 和 ctors,(我认为一旦他们看到你的 pojo 变得多么清晰,就没有人会要求这样做了)

于 2011-09-02T20:39:05.440 回答
13

我对 Lombok 的看法是,它仅提供了编写 boilerplate Java 代码的快捷方式。
在使用快捷方式编写 bolilerplate Java 代码时,我会依赖 IDE 提供的这些功能——就像在 Eclipse 中一样,我们可以转到菜单 Source > Generate Getters and Setter 来生成 getter 和 setter。
我不会为此依赖像 Lombok 这样的库:

  1. 它使用替代语法的间接层(读取,,等注释)污染您的@Getter代码@Setter。我不会学习 Java 的替代语法,而是切换到任何其他本机提供类似 Lombok 语法的语言。
  2. Lombok 需要使用 Lombok 支持的 IDE 来处理您的代码。这种依赖性为任何重要的项目带来了相当大的风险。开源 Lombok 项目是否有足够的资源来继续为各种可用 Java IDE 的不同版本提供支持?
  3. 开源 Lombok 项目是否有足够的资源来继续为将来出现的新版本 Java 提供支持?
  4. 我也很担心 Lombok 可能会与在运行时与您的字节码一起工作的广泛使用的框架/库(如 Spring、Hibernate、Jackson、JUnit、Mockito)引入兼容性问题。

总而言之,我不想用 Lombok 为我的 Java “增添趣味”。

于 2018-02-21T05:58:15.213 回答
10

想使用 lombok @ToString,但很快在 Intellij IDEA 中的项目重建中遇到随机编译错误。在增量编译成功完成之前必须多次点击编译。

在 jdk 1.6.0_39 和 1.6.0_45 下使用 Intellij IDEA 12.1.6 和 13.0 在没有任何 lombok 插件的情况下尝试了 lombok 1.12.2 和 0.9.3。

不得不从 delomboked 源手动复制生成的方法,并将 lombok 搁置到更好的时间。

更新

该问题仅在启用并行编译时发生。

提出问题: https ://github.com/rzwitserloot/lombok/issues/648

更新

mplushnikov 在 2016 年 1 月 30 日评论道:

较新版本的 Intellij 不再存在此类问题。我认为这里可以关闭。

更新

如果可能,我强烈建议从 Java+Lombok 切换到Kotlin。因为它从头开始解决了 Lombok 试图解决的所有 Java 问题。

于 2013-12-09T05:57:31.477 回答
6

我遇到了LombokJackson CSV的问题,当我将我的对象(java bean)编组为 CSV 文件时,列重复,然后我删除了 Lombok 的 @Data 注释并且编组工作正常。

于 2016-03-03T14:49:47.997 回答
1

我不推荐它。我曾经使用它,但是当我使用 NetBeans 7.4 时,它弄乱了我的代码。我必须在我的项目的所有文件中删除 lombok。有delombok,但我怎么能确定它不会弄乱我的代码。我不得不花几天时间来删除 lombok 并恢复到普通的 Java 样式。我就是太辣了...

于 2014-02-28T03:49:01.277 回答
-1

我还没有尝试过使用 Lombok - 它是/曾经是我列表中的下一个,但听起来 Java 8 给它带来了严重的问题,并且截至一周前,补救工作仍在进行中。我的来源是https://code.google.com/p/projectlombok/issues/detail?id=451

于 2014-04-29T13:27:51.963 回答