昊梵体育网

用了那么久的 Lombok,你知道它的原理么

天天用Lombok却不懂原理,手写生成器后我沉默了,你敢信?以前用Lombok的时候,感觉就是个黑科技,加个注解就能自动

天天用Lombok却不懂原理,手写生成器后我沉默了,你敢信?

以前用Lombok的时候,感觉就是个黑科技,加个注解就能自动生成getter、setter,省了好多事。但说实话,我一直没搞懂它到底是怎么做到的,心里总觉得有点虚。

后来看了一些资料,才知道Lombok根本不是魔法,它用的是Java编译器的一个标准接口,叫JSR 269。这个接口允许你在编译的时候插入自己的代码,去修改源代码的抽象语法树,也就是AST。

说白了,编译器在编译的时候,会把源码变成一棵树,每个节点代表一个类、方法或者变量。Lombok的注解处理器就在这棵树上动刀子,添上新的节点,然后编译器再把这些新节点变成字节码。所以它不影响运行时的性能,纯属编译期行为。

我决定自己动手弄一个简化版的Lombok,目标就是生成getter和setter。先写一个自定义注解,叫@MyGetterSetter,生命周期设成SOURCE,意思就是只在源码里有效,编译后就没影了。

然后写一个注解处理器,继承AbstractProcessor。在init方法里,我拿到了JavacTrees、TreeMaker、Names这三个工具,它们分别是用来获取AST、生成新节点、管理变量名的。

核心逻辑在process方法里。先找到所有被@MyGetterSetter标注的类,然后拿到这个类的AST对象。接着遍历类里的所有成员,找出那些字段节点,也就是JCTree.JCVariableDecl。

对每个字段,我用TreeMaker造出两个新的方法节点。一个setter,方法体里生成赋值语句;一个getter,方法体里生成返回语句。最后把这些新方法塞回类的成员列表里,用prepend方法加到最前面。

写完之后,我编译了处理器,注册到META-INF/services里,然后编译一个测试类Test.java。用javap反编译class文件,果然看到了自动生成的setWzj和getWzj方法。那一刻,感觉就像自己造了个小魔法。

虽然这个生成器很简单,但让我彻底明白了Lombok的原理。它不是什么黑盒,就是一个标准API加上AST操作。以前觉得Lombok很神秘,现在看透了,反而觉得挺踏实。

不过Lombok也不是完美的。它需要装IDE插件,否则代码提示会出问题。调试的时候,自动生成的代码也不那么直观。团队里如果有人没用过,还得花时间教他配置。

但话说回来,它确实能省很多时间。我写Java项目的时候,还是离不开它。只是现在用的时候,心里清楚它干了什么,不再是盲目相信了。

如果你也想试试,可以自己动手写一个。从最简单的getter/setter开始,慢慢就能理解怎么生成Builder模式、工厂模式了。Lombok本身有很多扩展点,比如@Builder、@Slf4j,都是类似的思路。

我觉得,掌握这个技术,以后遇到重复的代码,就能自己造个工具来解决,比复制粘贴靠谱多了。Java的编译期技术还在发展,以后可能会有更多玩法。至少现在,我敢说Lombok不是魔法,它就是个聪明的工具。

最后,如果你也好奇,不妨找个周末,照着网上的教程自己写一个。不用写多复杂,能生成一个getter就行。等你看到class文件里多出来的方法,你也会觉得,这玩意儿其实没那么玄乎。