写点什么

Java Nestmate 稳步推进

  • 2018-03-21
  • 本文字数:2072 字

    阅读完需:约 7 分钟

看新闻很累?看技术新闻更累?试试下载 InfoQ 手机客户端,每天上下班路上听新闻,有趣还有料!

Oracle 提出了 JEP 181“基于嵌套的访问控制”,即“Nestmate”。该 JEP 将是对 Java 平台的一次技术提升,可偿清 20 年前 Java 1.1 中存在的技术债务。

新特性与 Java 的嵌套类息息相关,嵌套类也时常被不严格地称为“内部类”,因为内部类是嵌套类的唯一可能类型。

一般来说,嵌套类型具有独立的两类用途,它们都与封装有关。

第一类用例是,嵌套类只可能在非常特定的原因下、在非常小范围的代码中需要。这意味着,嵌套类的确是实现细节的一部分,需要以紧密本地化的方式实现。

在旧版本的 Java 中,实现此用途的唯一方式是使用嵌套类型,例如使用内部类匿名实现接口。在实践中,随着 Java 8 的推出,该用例已经完全被使用 lambda 表达式和匿名类型所替代。虽然在一些情况下,依然使用近乎本地化类型,但是这类使用情况已经大幅度减少。

此外,类型可能是嵌套的。因为在一些情况下,一个类型需要具有对另一个类型内部的完全访问。这时该类型可实现为嵌套类型(即成员),就可以如同变量和方法那样,使用同样的方式实现访问。这意味着,嵌套类型具有访问特权,它可以认为是一种“对封装原则的略为放宽”。

另一类用例是,嵌套类型需要在某种程度上与其它类型绑定。这意味着,嵌套类型并不需要作为一个真正的实体,完全独立的存在,只是与其它的类型共存。

Nestmate JEP 的目的就是推广并形式化这种类型间的共生关系,进而厘清当前的实现。而当前的实现是一些技术债务,以现在的眼光看是相当黑科技的。

在 Java 10 中,嵌套类将编译为独立的顶层类文件,只是具有特殊的命名转换。例如,在Outer类内定义的嵌套类Nested,将被编译成一个名为Outer$Nested.class的文件。

实现该策略的问题在于,根据 Java 语言的规则,嵌套类具有访问其封闭类内的所有成员的权限,其中包括私有成员。

为解决该问题,javac将在Outer类中额外添加了允许访问的合成访问器(synthetic accessor)方法。举例说明,下面的代码定义了一个基本的内部类:

复制代码
public class Outer {
private int i = 0;
public class Inner {
public int i() {
return i;
}
}
}

编译该类,将生成两个类文件Outer.classOuter$Inner.class,字节码分别为:

复制代码
public class Outer {
private int i;
public Outer();
Code:
0: aload_0
1: invokespecial #2 // 方法 java/lang/Object."<init>":()V
4: aload_0
5: iconst_0
6: putfield #1 // 域 i:I
9: return
static int access$000(Outer);
Code:
0: aload_0
1: getfield #1 // 域 i:I
4: ireturn
}
</init>

复制代码
public class Outer$Inner {
final Outer this$0;
public Outer$Inner(Outer);
Code:
0: aload_0
1: aload_1
2: putfield #1 // 域 this$0:LOuter;
5: aload_0
6: invokespecial #2 // 方法 java/lang/Object."<init>":()V
9: return
public int i();
Code:
0: aload_0
1: getfield #1 // 域 this$0:LOuter;
4: invokestatic #3 // 方法 Outer.access$000:(LOuter;)I
7: ireturn
}
</init>

编译器将inner类所需的私有访问,转换为Outer类上的包内可见(package-private)访问器方法access$000()。具有这样的合成访问器,即便它并非原始类的一个 Nestmate,了解该机制的开发人员都可以直接的或者通过反射访问它。

作为 Java 路线图的一部分,对访问控制采取整理措施在嵌套类型上表现得尤为突出,需要做一些清理。动机正如 JEP 中所给出的:

嵌套将由对一组类文件的正式定义构成。其中,Nestmate 共享通用的访问控制机制,使所需的结果以更简单、更完全、更透明的方式实现。

在 JEP 描述中还指出,未来改进可能包括:

  • 在泛型特化(generic specialization)中,每个特化类型(specialized type)可被创建为泛型的一个 Nestmate。
  • 支持对Unsafe.defineAnonymousClass() API 的安全替换,实现将新类创建为已有类的 Nestmate。
  • 可能会影响“密封类”(sealed classes),仅允许 Nestmate 的子类作为密封类。
  • 可能会影响私有嵌套类型。私有嵌套类型当前定义为包内可访问(package-access)。

密封类和真正私有类型的概念,对于使用 Scala(以及其它一些支持这些概念的语言)的开发人员并不陌生,因为它们提供了实现一些理念所必须的构建模块。例如,在模式匹配等高级特性中十分有用的代数数据类型(ADT,algebraic data type)。

Nestmate 将作为 Valhalla 项目的一部分开发,目前实现初始原型的工作正在顺利开展。OpenJDK 开发人员正积极参与其中。

Oracle 通常并不会对 Nestmates 这样的长线特性将于何时交付给出任何承诺。鉴于 Nestmates 对于当前正在开发的其它一些里程碑功能(例如密封类和模式匹配)非常有用,感兴趣的 Java 程序员应关注该项目的不断成熟。

查看英文原文: Java Nestmates Makes Progress

2018-03-21 19:002472
用户头像

发布了 391 篇内容, 共 141.8 次阅读, 收获喜欢 257 次。

关注

评论

发布
暂无评论
发现更多内容

WorkPlus移动应用平台,完美的移动化办公体验

BeeWorks

WorkPlus即时通讯平台,让沟通变得简单高效

BeeWorks

WorkPlus Meet提供高度安全的私有化会议解决方案,保护企业隐私

BeeWorks

WorkPlus Meet提供高效、安全视频会议解决方案

BeeWorks

软件测试学习笔记丨Allure2测试用例描述相关用法(测试报告类别划分、名字展示等)

测试人

软件测试

客户说|从4小时到15分钟,一次分布式数据库的丝滑体验

阿里云瑶池数据库

数据库 云计算 阿里云 云原生 polarDB

人工智能测试开发训练营,快速掌握AI测试,更好职业机会晋升空间

测试人

软件测试 测试开发

快速掌握AI测试开发技能,获得更好的职业机会和晋升空间

霍格沃兹测试开发学社

亮点功能:流水线编辑支持并行了!

都广科技

DevOps

如何通过相对规模来估算用户故事?

敏捷开发

Scrum 敏捷 极限编程 用户故事 敏捷团队

云监控的核心:确保稳定性的关键监控指标

天翼云开发者社区

云计算 云服务 云监控

WorkPlus助力企业构建高效内部通讯与协作平台

BeeWorks

Java面试必考题之线程的生命周期,结合源码,透彻讲解!

不在线第一只蜗牛

Java 面试 生命周期 开发语言

Maple 2024 mac下载(含maple注册文件及破解工具)兼容m芯片

Rose

软件下载 Maple 2024 Maple数学软件 Maple 2024 mac破解

采购代购系统独立站,接口采集商品上货

Anzexi58

API 文档 外贸独立站

WorkPlus即时通讯平台,让沟通变得简单高效

BeeWorks

全球视角, 本土行动 —— 本地化商品管理之道

第七在线

10 个解放双手的 IDEA插件,少些冤枉代码(第三弹)

程序员小富

IDEA 插件

如何在弹性云主机上部署高效的数据库系统

天翼云开发者社区

数据库 云计算 弹性云主机

Java Nestmate稳步推进_Java_Ben Evans_InfoQ精选文章