JEP 181不兼容,嵌套类/ 2

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 "private"at 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.classReflThrow$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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346361.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

abap 导入队列末尾_在C#中将对象添加到队列的末尾-排队操作

要将对象添加到队列的末尾&#xff0c;代码如下-示例using System;using System.Collections.Generic;public class Demo {public static void Main(){Queue queue new Queue();queue.Enqueue("Electronics");queue.Enqueue("Accessories");queue.Enqueue…

vim循环下表复制_Vimrc Init.vim太长了?不存在的

精简配置刚开始接触vim&#xff0c;你会被它各种好看的外观以及实用的插件吸引&#xff0c;各种折腾&#xff0c;不知不觉你的vimrc或者init.vim变得特别长&#xff0c;我之前的init.vim有多长&#xff1f;596行&#xff1f;wtf&#xff1f;每次维护的时候不知道有多麻烦&#…

C语言与JAVA内存管理_C语言内存管理

本章将介绍C语言动态内存管理. C语言编程语言提供了多种功能的内存分配和管理。这些函数可以在头文件中找到。S.N.函数与说明1void *calloc(int num, int size);此函数分配num元素其中每一个字节大小为(size)的数组2void free(void *address);此函数释放由地址指定的存储器块的…

使用LocalDate,LocalTime和LocalDateTime

Java 8对日期和时间API进行了重大更改&#xff0c;这是在JSR 310&#xff1a;日期和时间API的 JDK中包括了Joda Time API 。 此JSR由Joda Time的创建者Stephen Colebourne领导。 有许多惊人的API可用于日期和时间。 在本文中&#xff0c;我将介绍最常用的&#xff1a; java.ti…

visual studio odbc数据源设计器_NEW!WinForm界面开发设计时正式支持.NET 5

点击“了解更多”获取DevExpress v20.2完整版下载早在今年7月&#xff0c;官方技术团队宣布对DevExpress控件进行功能增强&#xff0c;使其支持最新的.NET 5 Preview。 但是尽管技术团队一直在努力确保WinForms控件与.NET 5兼容但在Visual Studio中对设计器的支持却是另一回事。…

java 接口的观察者模式_java观察者模式

观察者模式又叫做发布-订阅(Publish/Subscribe)模式。观察者模式定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时&#xff0c;会通知所有观察者对象&#xff0c;使它们能够自己更新自己。Observer结构图.pngSubj…

java 构建者模式_Java方法中的参数太多,第3部分:构建器模式

java 构建者模式在我的前两篇文章中&#xff0c;我研究了如何通过自定义类型和参数对象减少构造函数或方法调用所需的参数数量。 在本文中&#xff0c;我将讨论如何使用构建器模式来减少构造器所需的参数数量&#xff0c;并讨论该模式如何甚至可以帮助采用过多参数的非构造器方…

webgis从基础到开发实践_ArcGIS API For Javascript 开发笔记(四)

二、应用篇1、应用部署部署也就意味着一个 DEMO 或者系统即将完工&#xff0c;也意味着系统即将上线&#xff0c;相对来说Javascript 应用的部署不是很复杂&#xff0c;但是这是有前提的&#xff0c;要对部署中的一些概念有所了解&#xff0c;比如部署中常常提到的虚拟目录&…

Spock 1.2 –轻松进行集成测试中的Spring Bean模拟

探索如何使用Spock 1.2将Spock的模拟和间谍自动注入到Spring上下文中。 Spock中的存根/模拟/间谍&#xff08;及其生命周期&#xff09;一直与Spock Specification类紧密结合。 只能在测试类中创建它们。 因此&#xff0c;使用共享的预定义模拟&#xff08;在单元测试和集成测…

geteditor p 取消自动_2020百度网盘超级会员怎么取消自动续费?

首先我们打开百度网盘&#xff0c;开通超级会员以后&#xff0c;可以看到个人中心有一个管理自动续费的&#xff0c;点击打开。2然后可以看到自己开通的界面旁边显示的有一个取消按钮。3点击取消以后&#xff0c;会提示我们自动续费享受的有优惠&#xff0c;我们继续点击确认取…

java堆和客栈_java中堆和栈的区别分析

堆和栈是java数据结构里非常重要的概念&#xff0c;本文较为详细的分析了二者之间的区别。供大家参考。具体如下&#xff1a;Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarr栈的优势是&#xff0c;存取速度比堆要快&a…

php odbc驱动,用于Windows的PHP 7.0 ODBC驱动程序

我将PHP 5.6.30(https://www.apachefriends.org/de/download.html)升级到PHP 7.0(https://bitnami.com/stack/wamp/installer)到目前为止,一切都运行良好,当我使用MySQL数据库时,它将我的页面的加载时间从1,2秒减少到约300毫秒.但是现在我正在尝试使用以下简单脚本连接到MSSQL数…

分布式机器学习_229页,CMU博士张昊毕业论文公布,探索机器学习并行化的奥秘...

CMU 机器人研究所张昊&#xff08;Hao Zhang&#xff09;博士论文新鲜出炉&#xff0c;主要围绕着机器学习并行化的自适应、可组合与自动化问题展开。机器之心报道&#xff0c;机器之心编辑部。随着近年来&#xff0c;机器学习领域的创新不断加速&#xff0c;SysML 的研究者已经…

利用Excel或LibreOffice的业务输入进行单元测试约束

业务专家向我们&#xff08;开发人员&#xff09;解释业务限制。 但是&#xff0c;如何确保我们正确理解它们呢&#xff1f; 或更糟糕的是&#xff0c;一旦约束条件正式化&#xff0c;我们如何测试他们之间是否同意&#xff1f; 好吧&#xff0c;有一种很棒的方法可以做到这一…

Java播放歌词同步源码,Android 实现歌词同步

歌词同步的原理其实很简单&#xff1a;歌词显示是一个线程&#xff0c; 音乐播放时一个线程&#xff0c;通过播放时间将歌词显示进度与播放进度同步起来。网络标准的歌词格式是LRC。 我们看下一个LRC文档&#xff0c;其格式就一目了然了。[ti&#xff1a;爱][ar&#xff1a;小虎…

矩阵连乘 动态规划_Java动态规划

1. 介绍动态规划典型的被用于优化递归算法&#xff0c;因为它们倾向于以指数的方式进行扩展。动态规划主要思想是将复杂问题(带有许多递归调用)分解为更小的子问题&#xff0c;然后将它们保存到内存中&#xff0c;这样我们就不必在每次使用它们时重新计算它们。要理解动态规划的…

c php乱码,php分割GBK中文乱码的解决方法

类似如下的字符串(GBK), explode不能得到正确结果:$result explode("|", "滕华弢|海青");究其原因, 对于”弢”字(读tao,不认识没关系,我也不认识), 因为他的GBK编码值为: 8f7c, 不巧的是, “|”的ASCII值也是7c.还有一些类似的问题: 因为GBK编码的编码范…

分布式光伏补贴_光伏发电上网电价政策综述

原标题&#xff1a;光伏发电上网电价政策综述近些年&#xff0c;光伏发电上网电价相关政策不断推陈出新&#xff0c;在推进平价上网的同时&#xff0c;也积极对接了电力市场建设需要。本文梳理了光伏发电上网电价及补贴标准有关政策&#xff0c;供参考使用&#xff1a;1.普通光…

怎么简单的锁定文件夹_简单性与鲁棒性–在锁定文件处理中展示

怎么简单的锁定文件夹今天&#xff0c;我们将讨论使事情保持简单&#xff0c;愚蠢&#xff08;KISS&#xff09;和鲁棒性的设计价值之间&#xff0c;设计不足和过度设计之间的冲突。 我们正在编写一个批处理Java应用程序&#xff0c;需要确保在服务器上一次最多运行一个实例。…

php strlen 线程安全,浅析PHP中strlen和mb_strlen的区别

在PHP中&#xff0c;strlen与mb_strlen是求字符串长度的函数&#xff0c;但是对于一些初学者来说&#xff0c;如果不看手册&#xff0c;也许不太清楚其中的区别。下面通过例子&#xff0c;讲解这两者之间的区别。先看例子&#xff1a;//测试时文件的编码方式要是UTF8$str中文a字…