sneaky visit( 三 )

⑨ SneakyThrows 使用public class ThrowsTest {@SneakyThrows()public void read() {InputStream inputStream = new FileInputStream("");}@SneakyThrowspublic void write() {throw new UnsupportedEncodingException();}// 相当于public void read() throws FileNotFoundException {InputStream inputStream = new FileInputStream("");}public void write() throws UnsupportedEncodingException {throw new UnsupportedEncodingException();}}⑩ Synchronized 使用public class SynchronizedDemo {@Synchronizedpublic static void hello() {System.out.println("world");}// 相当于private static final Object $LOCK = new Object[0];public static void hello() {synchronized ($LOCK) {System.out.println("world");}}}? Getter(lazy = true) 使用public class GetterLazyExample {@Getter(lazy = true)private final double[] cached = expensive();private double[] expensive() {double[] result = new double[1000000];for (int i = 0; i < result.length; i++) {result[i] = Math.asin(i);}return result;}}// 相当于import java.util.concurrent.atomic.AtomicReference;public class GetterLazyExample {private final AtomicReference cached = new AtomicReference<>();public double[] getCached() {java.lang.Object value = https://www.baikexueshe.com/s/this.cached.get();if (value == null) {synchronized (this.cached) {value = this.cached.get();if (value == null) {final double[] actualValue = expensive();value = actualValue == null ? this.cached : actualValue;this.cached.set(value);}}}return (double[]) (value == this.cached ? null : value);}private double[] expensive() {double[] result = new double[1000000];for (int i = 0; i < result.length; i++) {result[i] = Math.asin(i);}return result;}}原理分析我们知道 Java 的编译过程大致可以分为三个阶段:

  1. 解析与填充符号表
  2. 注解处理
  3. 分析与字节码生成
编译过程如下图所示:
sneaky visit

文章插图

而 Lombok 正是利用「注解处理」这一步进行实现的 , Lombok 使用的是 JDK 6 实现的 JSR 269: Pluggable Annotation Processing API (编译期的注解处理器)  , 它是在编译期时把 Lombok 的注解代码 , 转换为常规的 Java 方法而实现优雅地编程的 。


这一点可以在程序中得到验证 , 比如本文刚开始用 @Data 实现的代码:
sneaky visit

文章插图



在我们编译之后 , 查看 Person 类的编译源码发现 , 代码竟然是这样的:
sneaky visit

文章插图

可以看出 Person 类在编译期被注解翻译器修改成了常规的 Java 方法 , 添加 Getter、Setter、equals、hashCode 等方法 。


Lombok 的执行流程如下:
sneaky visit

文章插图

可以看出 , 在编译期阶段 , 当 Java 源码被抽象成语法树 (AST) 之后 , Lombok 会根据自己的注解处理器动态的修改 AST , 增加新的代码 (节点) , 在这一切执行之后 , 再通过分析生成了最终的字节码 (.class) 文件 , 这就是 Lombok 的执行原理 。


手撸一个 Lombok我们实现一个简易版的 Lombok 自定义一个 Getter 方法 , 我们的实现步骤是:
  1. 自定义一个注解标签接口 , 并实现一个自定义的注解处理器;
  2. 利用 tools.jar 的 javac api 处理 AST (抽象语法树)
  3. 使用自定义的注解处理器编译代码 。
这样就可以实现一个简易版的 Lombok 了 。
1.定义自定义注解和注解处理器首先创建一个 MyGetter.java 自定义一个注解 , 代码如下:


特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。