写点什么

Java 枚举增强,提供更强的类型支持

  • 2017-01-12
  • 本文字数:1564 字

    阅读完需:约 5 分钟

最新的 JEP 上显示,Java 枚举将增强泛型支持,并能将方法添加到单个项目上去。这两个功能可以通过一次更改进行交付,原因是它们捆绑在了一起。更改仅仅会影响到 Java 编译器,因此不需要运行时更改。虽然没有目标版本,但可能会在 Java 10 中呈现更改。

一开始这个更改没有得到很大的肯定,比如杰出的 Java Champions Joshua Bloch 就其实用性提出了质疑。然而,通过进一步的讨论和新用例的介绍帮助它逐步获得了支持。

以防你没有看到我对 @BrianGoetz 的回应,我已经看到了 JEP 列出的介绍,我也撤回了我先前对这个变更的不看好观点。用例: https://t.co/O1tJO8oSCp
——Joshua Bloch (@joshbloch) 2016 年 12 月 7 日

让我们一起通过 JEP 中举出的用例和一些其他讨论来总结一下这次变更给开发者带来了什么改变。Java Champion Lukas Eder 提出了一个 StackOverflow 的问题,介绍了通过配置文件、web 会话或类似类型安全的方式检索和设置属性的用例。带有泛型支持的枚举让我们可以指示一组可用的键和它们相关联的类型:

复制代码
public enum Key<T> {
HOST<String>,
PORT<Integer>,
SCORE<Double>
}
public interface PropertiesStore {
public <T> void put(Key<T> key, T value);
public <T> T get(Key<T> key);
}

现在,这些键可以安全地在属性存储中进行检索和存储,因为下面的表达式将无法编译:

复制代码
put(PORT, “not a number”); // error, type mismatch: PORT is Key<Integer>
// “not a number” is String

另一方面,允许单个项目有自己的方法可以帮助定义只适用于某些属性的操作。根据 JEP 301 所述,上述定义可以扩展如下:

复制代码
public enum Key<T> {
HOST<String>,
PORT<Integer>,
SCORE<Double> {
double normalise(double x) {
// score normalisation logic
return result;
}
}
}

根据当前的枚举,所有项目都有通用类型 Key,这意味着方法 normalise 将不可见。但是在这项工作完成后,编译器将会保留这类型信息,这代表着以下的将为真:

复制代码
SCORE.normalise(5.37); // compiles
HOST.normalise(5.37); // error: neither HOST nor Key have normalise

要实现这一点,需要改变计算各个枚举项目的静态类型的方式。正如读者可能知道的一样,枚举在 Java 5 中仅仅作为纯粹的语法上的甜头而添加:JVM 对枚举没有任何特殊的处理,而是由编译器将枚举转换为带有静态对象的普通类,然后将其编译为字节码。抛开一切技术方面的问题,下面的枚举:

复制代码
public enum Colour {
RED, GREEN, BLUE
}

由编译器粗糙地进行了转换,如下(这不是一个非常准确的表达,但是足以解释清楚):

复制代码
public class Colour extends Enum {
public static final Colour RED = new Colour();
public static final Colour GREEN = new Colour();
public static final Colour BLUE = new Colour();
private Colour() {}
}

由于所有项目的类型是 Colour,任何项目特定的方法和类型信息都会丢失。 JEP 301 要做的是确定使用通用枚举类型不足以表示单个项目的情况,在这种情况下生产更多更具体的类型,如Colour$REDColour$GREENColour$BLUE

增强的枚举甚至可以从 JDK 其他部分正在进行的工作中受益。一方面,局部变量类型推断可以让开发人员获得由编译器创建的更清晰的类型,即使这些类型的确切形式在编写代码的时候是未知的,这意味着上面的代码可能是以下这样的:

复制代码
var s = Key.SCORE; // type of s derived as Key$SCORE
s.normalise(8.29); // method normalise can be accessed

另一方面,一些证据和用例都表示枚举中的泛型可能更加广泛地使用于原始类型,这是相当低效的(JVM 必须为每个原始类型使用装盒后对应类型)。这可以通过 Valhalla 项目处理原始类型的泛型这个部分消除障碍,并使其可用于大规模使用。

查看英文原文 Java Enums to Be Enhanced with Sharper Type Support

2017-01-12 18:005475
用户头像

发布了 218 篇内容, 共 79.9 次阅读, 收获喜欢 76 次。

关注

评论

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

并发王者课-铂金7:整齐划一-CountDownLatch如何协调多线程的开始和结束

MetaThoughts

Java 多线程 并发

Rust从0到1-Cargo-安装来自Crates.io的程序

rust cargo install

iOS不行?还是个人能力有限?

ios 程序员 IT 编程之路

CDH安装搭建(一)

大数据技术指南

CDH 7月日更

排序——插入排序

若尘

数据结构 排序 排序算法 插入排序

GrowingIO Design 组件库搭建之Select组件

GrowingIO技术专栏

select 组件实现 virtualList

并发王者课-铂金6:青出于蓝-Condition如何把等待与通知玩出新花样

MetaThoughts

Java 多线程 并发

为什么nginx主机的io使用率会100%?

BUG侦探

nginx proxy_buffering docker镜像

数字经济时代,国家与国家的核心竞争力就是算力

CECBC

分布式认知工业互联网

CECBC

架构实战营模块1课后作业

蔸蔸

并发王者课-铂金8:峡谷幽会-看CyclicBarrier如何跨越重峦叠嶂

MetaThoughts

Java 并发 多线

Ubuntu Server 20.04安装KVM虚拟机

玏佾

ubuntu 虚拟机 Ubuntu20.04 kvm

双非小伙暑期实习斩获腾讯WXG offer,这不比博人传燃?

北游学Java

Java 腾讯 面试

必看!史上最全云原生全景图解读攻略来啦

尔达Erda

容器 微服务 运维 云原生 技术人

Java开发从二面被拒到收割阿里架构offer,我花了一年时间,复盘成功经历!

Java架构追梦

Java 阿里巴巴 架构 offer 成长笔记

CloudQuery 使用教程 No.4 数据查询(下)

BinTools图尔兹

dba 数据库管理工具 国产数据库 运维开发

论文解读丨文档结构分析

华为云开发者联盟

模型 文档 文档结构分析 分割 文档结构

iOS开发 · iOS音视频开发 - ARKit 教学:如何搭配SceneKit来建立一个简单的ARKit Demo

iOSer

ios ios开发 ARKit iOSAR.

阿里P8耗时半年总结的Java核心面试知识,助我轻松拿下蚂蚁offer

Java 程序员 面试 java编程 java技术宅

合肥智慧社区平台建设解决方案,平安小区建设

涨薪50%,从小厂逆袭,坐上美团L8技术专家(面经+心得)

Java 编程 程序员 面试

基于MaxCompute快速打通数据仓库和数据湖的湖仓一体实践

阿里云大数据AI技术

疯了吧!这帮人居然用 Go 写“前端”?(一)

尔达Erda

开发者 云原生 大前端 后端 开发

多维数据分析(OLAP)技术选型(1):对什么进行选型

水滴

OLAP 通信协议 技术选型 多维分析 存储格式

动手训练属于自己的无人车,这个超强服务现已开源!

亚马逊云科技 (Amazon Web Services)

阿里技术分享:闲鱼IM基于Flutter的移动端跨端改造实践

JackJiang

flutter 即时通讯 IM

不愧是阿里内部“SpringCloudAlibaba学习笔记”竟然在GitHub霸榜月余

Java 编程 架构 微服务

Flink 的底层API

五分钟学大数据

flink 7月日更

一文讲懂Hive高可用、HiveServer2高可用及Metastore高可用

白贺BaiHe

数据仓库 7月日更 HiveServer2高可用 Metastore高可用 Hive高可用

架构实战营 模块一作业

面向对象的猫

「架构实战营」

Java枚举增强,提供更强的类型支持_Java_Abraham Marín Pérez_InfoQ精选文章