From 458d588f48352cbb2c9a9512f97e70d8a5302b3c Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Sun, 28 Jun 2020 22:53:21 +0800 Subject: [PATCH] =?UTF-8?q?Update=20JVM=20=E7=9B=B8=E5=85=B3=E5=8F=A3?= =?UTF-8?q?=E6=B0=B4=E8=AF=9D.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blogs/Java/口水话/JVM 相关口水话.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/blogs/Java/口水话/JVM 相关口水话.md b/blogs/Java/口水话/JVM 相关口水话.md index 2cc8b9b..04a9db0 100644 --- a/blogs/Java/口水话/JVM 相关口水话.md +++ b/blogs/Java/口水话/JVM 相关口水话.md @@ -23,6 +23,7 @@ JVM 相关口水话 11. JVM 是如何实现反射的? 12. JVM 是如何实现泛型的? 13. JVM 是如何实现异常的? +14. JVM 是如何实现注解的? #### 内存区域 @@ -196,6 +197,8 @@ JVM 也提供了内联缓存来加快动态绑定,它能够缓存虚方法调 #### JVM 是如何实现泛型的? +除了泛型擦除,我还真的没啥可讲的了,毕竟也就只有这点东西。 + #### JVM 是如何实现异常的? 在 Java 中,所有的异常都是 Throwable 类或其子类,它有两大子类 Error 和 Exception。 当程序触发 Error 时,它的执行状态已经无法恢复,需要终止线程或者终止虚拟机,常见的比如内存溢出、对栈溢出等;Exception 又分为两类,一类是受检异常,比如 IOException,一类是运行时异常 RuntimeException,比如空指针、数组越界等。 @@ -206,4 +209,10 @@ JVM 也提供了内联缓存来加快动态绑定,它能够缓存虚方法调 其次是,JVM 捕获异常需要异常表。每个方法都有一个异常表,异常表中的每一个条目都代表一个异常处理器,并且由 from、to、target 指针及其异常类型所构成。form-to 其实就是 try 块,而 target 就是 catch 的起始位置。当程序触发异常时,JVM 会坚持触发异常的字节码的索引值落到哪个异常表的 from-to 范围内,然后再判断异常类型是否匹配,匹配就开始执行 target 处字节码处理该异常。 -最后是 finally代码块的编译。我们知道 finally 代码块一定会运行的(除非虚拟机退出了)。那么它是如何实现的呢?其实是一个比较笨的办法,当前 JVM 的做法是,复制 finally 代码块的内容,分别放在所有可能的执行路径的出口中。 \ No newline at end of file +最后是 finally代码块的编译。我们知道 finally 代码块一定会运行的(除非虚拟机退出了)。那么它是如何实现的呢?其实是一个比较笨的办法,当前 JVM 的做法是,复制 finally 代码块的内容,分别放在所有可能的执行路径的出口中。 + +#### JVM 是如何实现注解的? + +其实也没啥银弹,主要就是要知道注解信息是存放在哪的?在 Java 字节码中呢是通过 RuntimeInvisibleAnnotations 结构来存储的,它是一个 Annotations 数组,毕竟类、方法、属性是可以加多个注解的嘛。在数组中的每一个元素又是一个 ElementValuePair 数组,这个里面存储的就是注解的参数信息。 + +运行时注解可以通过反射去拿这些信息,编译时注解可通过 APT 去拿,基本上就没啥东西了。 \ No newline at end of file