网站如何做进一步优化,哔哩哔哩网页版网址入口,无锡便宜做网站,校园网站建设平台JEP 181是基于嵌套的访问控制https://openjdk.java.net/jeps/181 。 它是在Java 11中引入的#xff0c;它故意引入了与先前版本的不兼容性。 这是一个很好的例子#xff0c;与Java的先前版本兼容并不是刻板的规则#xff0c;而是保持语言的一致性和稳定发展。 在本文中… JEP 181是基于嵌套的访问控制https://openjdk.java.net/jeps/181 。 它是在Java 11中引入的它故意引入了与先前版本的不兼容性。 这是一个很好的例子与Java的先前版本兼容并不是刻板的规则而是保持语言的一致性和稳定发展。 在本文中我将通过几年前遇到的一个例子来研究这种变化以及在这种特殊情况下Java 11如何使生活更轻松更一致。 Java向后兼容性仅限于功能而非行为 原始情况 几年前当我编写可以用Java方法扩展的ScriptBasic for Java解释器时就好像它们是用BASIC编写的一样可用时我创建了一些单元测试。 单元测试类包含一些内部类其中具有一些可用于BASIC代码的方法。 内部类是静态和私有的因为它与除测试以外的任何其他类均无关但是该类和方法仍可被测试代码访问因为它们位于同一类中。 令我沮丧的是这些方法无法通过BASIC程序访问。 当我尝试通过本身正在使用反射访问的BASIC解释器调用方法时出现了IllegalAccessException 。 为了纠正这种情况经过几个小时的调试和学习我创建了以下简单代码 package javax0;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class ReflThrow {private class Nested {private void m(){System.out.println(m called);}}public static void main(String[] args)throws NoSuchMethodException,InvocationTargetException,IllegalAccessException {ReflThrow me new ReflThrow();Nested n me.new Nested();n.m();Method m Nested.class.getDeclaredMethod(m);m.invoke(n);}
} 如果使用Java N其中N 11运行此代码则将得到类似以下内容 m called
Exception in thread main java.lang.IllegalAccessException: class ReflThrow cannot access a member of class ReflThrow$Nested with modifiers privateat java.base/jdk.internal.reflect.Reflection.throwIllegalAccessException(Reflection.java:423)at java.base/jdk.internal.reflect.Reflection.throwIllegalAccessException(Reflection.java:414)
... 但是它可以在Java 11上正常运行并且大概在更高版本的Java中也可以正常运行。 说明 直到Java 11版本JVM都不处理内部和嵌套类。 JVM中的所有类都是顶级类。 Java编译器从内部和嵌套类创建一个特别命名的顶级类。 例如其中一个Java编译器可以创建类文件ReflThrow.class和ReflThrow$Nested.class 。 因为它们是JVM的顶级类所以当ReflThrow类是两个不同的顶级类时它们中的代码无法调用Nested的私有方法m() 。 但是在Java级别从嵌套结构创建这些类是可能的。 为了实现这一点编译器在Nested类中创建了一个额外的综合方法 ReflThrow中的代码可以调用该方法而Nested已经存在的该方法将调用m() 。 合成方法具有修饰符SYNTHETIC因此编译器稍后知道其他代码不应“看到”这些方法。 这样调用方法m()效果很好。 另一方面当我们尝试使用名称和反射访问来调用方法m() 路由将直接通过类边界而无需调用任何合成方法并且由于该方法对于它所在的类是私有的因此调用引发异常。 Java 11对此进行了更改。 结合到已经发布的Java 11中的JEP 181引入了概念嵌套。 “嵌套允许类在逻辑上属于同一代码实体但被编译成不同的类文件而无需编译器插入可扩展访问性的桥方法即可访问彼此的私有成员。” 它仅表示存在作为嵌套的类并且存在属于嵌套的类。 从Java生成代码时顶级类是嵌套类而内部的类是嵌套的。 JVM级别的此结构为不同的语言结构留有很大空间并且不会在执行环境中出现Java结构的麻烦。 JVM旨在成为多语言的并且随着将来GraalVM的引入它甚至将成为“更多”的多语言。 使用这种结构的JVM只是看到两个类在同一个嵌套中因此它们可以互相访问private方法字段和其他成员。 这也意味着没有桥接方法具有不同的访问限制并且反射与普通的Java调用完全通过相同的访问边界。 摘要/外卖 Java不会一夜之间发生变化并且大部分是向后兼容的。 但是向后兼容性仅限于功能而非行为。 JEP181没有并且它从未真正打算重现对嵌套类的反射访问的并非绝对完美的IllegalAccessException抛出行为。 此行为是实现行为/错误而不是语言功能并且已在Java 11中修复。 翻译自: https://www.javacodegeeks.com/2018/10/jep-181-incompatibility-nesting-classes.html