美国上市公司,专注Java培训22年

Java教程-Java枚举的高阶功能


很多初学者在刚开始使用枚举的时候觉得它只是一个给常量命名的工具,比如 static constant String ENUM_VAL_NAME。

但其实Java的枚举还有很多先进的功能,这些功能可以帮助开发者写出更简洁且不易出错的代码。

接下来我会列举一些Java的高级枚举功能,以及如何利用这些功能来使得开发更高效,更具可读性。

一、枚举是类

首先,我们要确认一点,枚举是Java的一个类。

比如创建下面一段代码,枚举的基类Enum<E>

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() {

return 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()

二、Java中的Operation枚举

enum Operation { ADD, SUBTRACT, MULTIPLY}

此枚举表示可以对两个值操作并将产生结果。

一般来说,初学者更偏向于使用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添加新操作,编译器不会通知此switch没有正确处理新的操作。

②遇到default情况,就算我们知道它永远不会发生,这也是必需的。

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

三、功能枚举实现

由于枚举是类,我们可以创建一个枚举字段来保存函数。如何来完成这一操作?首先,让我们将开关放在枚举类中。

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);

上述代码中是从 inside 调用方法Operation,可以将其更改为实例方法,并使用this关键字,而不是将所需的Operation作为参数传递。

public int apply(int arg1, int arg2) {

switch(this) {

case ADD:

return arg1 + arg2;

case SUBTRACT:

return arg1 - arg2;

case MULTIPLY:

return arg1 * arg2;

default:

throw new UnsupportedOperationException();

}

}

像这样调用加法操作:Operation.ADD.apply(2, 3);

现在让我们更进一步,通过使用函数式编程完全消除 switch 语句。

enum Operation {ADD((x, y) -> x + y),SUBTRACT((x, y) -> x - y),MULTIPLY((x, y) -> x * y);

Operation(BiFunction<Integer, Integer, Integer> operation)

{this.operation = operation;}

private final BiFunction<Integer, Integer, Integer> operation; public int apply(int x, int y)

{return operation.apply(x, y);

}

}

上述代码中做了三件事:

1.添加了一个BiFunction<Integer, Integer, Integer> operation字段。

2.Operation使用BiFunctionarg创建了一个构造函数。

3.调用构造函数BiFunction<Integer, Integer, Integer>并用lambda指定。该java.util.function.BiFunction operation字段是对带有两个参数的函数(方法)的引用。在上述代码示例中,两个参数都是整数,返回值也是整数。但是Java 参数化类型不支持原语,因此必须使用Integer。

新Operation实现以相同的方式使用:Operation.ADD.apply(2, 3),

但是,这种实现会比switch好一些,因为编译器会在Operation添加新功能时会要求开发者实现新功能。

四、关键要点

Java 枚举是扩展Enum<T>.

枚举可以有字段、构造函数和实例方法。

Java 枚举字段可以存储函数与 lambda 配合使用,也可以创建一个函数的干净、安全的特定于枚举的实现,并在编译时强制执行(不使用switch)。


【免责声明】本文部分系转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,如涉及作品内容、版权和其它问题,请在30日内与我们联系,我们会予以重改或删除相关文章,以保证您的权益!

Java开发高端课程免费试学

大咖讲师+项目实战全面提升你的职场竞争力

  • 海量实战教程
  • 1V1答疑解惑
  • 行业动态分析
  • 大神学习路径图

相关推荐

更多
  • eclipse怎么建立Java项目?
    eclipse怎么建立Java项目?
    eclipse怎么建立Java项目?在使用Eclipse建立Java项目时,可以遵循以下步骤: 详情>>

    2024-05-10

  • Java关键词汇总-Java关键字有哪些及其作用?
    Java关键词汇总-Java关键字有哪些及其作用?
    Java关键词汇总-Java关键字有哪些及其作用?Java语言中的关键字(Keywords)是Java编程语言的核心组成部分,它们具有特定的意义,并被用于表示基本数据类型、控制语句、访问权限等。Java关键字总数大约有50个左右,下面列出了一些常用的Java关键字及其作用: 详情>>

    2024-04-08

  • Java编程工具用哪个最好
    Java编程工具用哪个最好
    Java编程工具用哪个最好?Java编程工具的选择取决于个人的偏好、项目需求和开发环境。以下是一些常用的Java编程工具: 详情>>

    2024-04-03

  • 好用的Java编写软件
    好用的Java编写软件
    Java是一种广泛使用的编程语言,因其跨平台、安全性和稳定性而受到许多开发者的喜爱。Java被用于开发各种类型的软件,从桌面应用程序到企业级服务器端应用程序。以下是一些常见的、用Java编写的软件示例: 详情>>

    2024-04-02

  • Java开班时间

    收起