写点什么

你一定需要知道的高阶 JAVA 枚举特性!

  • 2022 年 5 月 15 日
  • 本文字数:1438 字

    阅读完需:约 5 分钟

后来我发现我错了。事实证明,Java 枚举具有相当高级的特性,可以使代码干净、不易出错,功能强大。


让我们一起来看看 Java 中的一些高级枚举特性,以及如何利用这些特性使代码更简单、更可读。

枚举是类!

在 Java 中,枚举是 Object 的一个子类。让我们看看所有枚举的基类,Enum (为简洁起见进行了修改)。


public abstract class Enum<E extends Enum<E>>


implements Constable, Comparable<E>, Serializable {


private final String name;


public final String name() {


return name;


}


private final int ordinal;


public final int ordinal() {


return ordinal;


}


protected Enum(String name, int ordinal) {


this.name = name;


this.ordinal = ordinal;


}


public String toString() {


r 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 eturn name;


}


public final boolean equals(Object other) {


return this==other;


}


public final int hashCode() {


return super.hashCode();


}


public final int compareTo(E o) {


Enum<?> other = (Enum<?>)o;


Enum<E> self = this;


if (self.getClass() != other.getClass() && // optimization


self.getDeclaringClass() != other.getDeclaringClass())


throw new ClassCastException();


return self.ordinal - other.ordinal;


}


}


我们可以看到,这基本上只是一个常规的抽象类,有两个字段,name 和 ordinal。


所以说枚举都是类,所以它们具有常规类的许多特性。


我们能够为枚举提供实例方法、构造函数和字段。我们可以重写 toString(),但不能重写 hashCode()或 equals(Object other)。


接下来我们看下我们的枚举示例,Operation


enum Operation {


ADD,


SUBTRACT,


MULTIPLY


}


这个枚举表示一个 Operation 可以对两个值执行,并将生成一个结果。关于如何实现此功能,您最初的想法可能是使用 switch 语句,如下所示:


public int apply(Operation operation, int arg1, int arg2) {


switch(operation) {


case ADD:


return arg1 + arg2;


case SUBTRACT:


return arg1 - arg2;


case MULTIPLY:


return arg1 * arg2;


default:


throw new UnsupportedOperationException();


}


}


当然,这样子会有一些问题。


第一个问题是,如果我们将一个新操作添加到我们的枚举 Operation 中,编译器不会通知我们这个开关不能正确处理新操作。


更糟糕的是,如果一个懒惰的开发人员在另一个类中复制或重新编写这些代码,我们可能无法更新它。


第二个问题是默认情况 default,每段程序里面都是必需的,尽管我们知道在正确的代码里它永远不会发生。


这是因为 Java 编译器知道上面的第一个问题,并且希望确保我们能够处理在不知情的情况下向 Operation 中添加了新枚举。


还好,Java8 用函数式编程为我们提供了一个干净的解决方案。

函数枚举实现

因为枚举是类,所以我们可以创建一个枚举字段来保存执行操作的函数。


但是在我们找到解决方案之前,让我们先来看看一些重构。


首先,让我们把开关放在 enum 类中。


enum Operation {


ADD,


SUBTRACT,


MULTIPLY;


public static int apply(Operation operation, int arg1, int arg2) {


switch(operation) {


case ADD:


return arg1 + arg2;


case SUBTRACT:


return arg1 - arg2;


case MULTIPLY:


return arg1 * arg2;


default:


throw new UnsupportedOperationException();


}


}


}


我们可以这样做:Operation.apply(Operation.ADD, 2, 3);


因为我们现在从 Operation 中调用方法,所以我们可以将其更改为实例方法并使用 this,而不是用 Operation.apply()来实现,如下所示:

用户头像

还未添加个人签名 2022.04.13 加入

还未添加个人简介

评论

发布
暂无评论
你一定需要知道的高阶JAVA枚举特性!_Java_爱好编程进阶_InfoQ写作社区