Java中的枚举与values()方法

简介:

在编写Java程序时经常会用到枚举(后面统一用enum描述)类型,今天我们就来看一下enum中常用到的values()方法。

首先,我们在Eclipse中编写一个简单的类:

public class EnumTest {
    private enum Directions {
        NORTH, SOUTH, EAST, WEST
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

在这里,我们定义了一个名叫Directions的enum,它其中包含了四个方向。 
接下来,我们写一个简单的main函数,仅仅是调用values()方法:

public static void main(String[] args) {
    Directions.values();
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

在Eclipse中,我们点击某个函数、变量时,会跳转到其相应的源码位置。在此处我们尝试点击values()方法,却是没有反应的,这是为什么呢? 
此外,我们在定义Directions这个enum类型时,使用的是enum这个java关键字,那么这里又是如何调用到values()方法的? 
为此,我们需要了解一下enum关键字背后是如何实现的。

最直接的方法就是查阅JDK的文档了,oracle在线文档的地址在这里: 
http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html 
篇幅不是很长,其中恰好有两段说明可以解释我们的两个问题:

The enum declaration defines a class (called an enum type). The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.

首先,enum声明实际上定义了一个类。因此我们可以通过定义的enum调用其方法。其次,Java编译器会自动在enum类型中插入一些方法,其中就包括values()——所以我们的程序在没编译的时候,自然没法查看values()方法的源码了。

那么这个enum是一个什么类呢?接下来还有这样一段说明:

All enums implicitly extend java.lang.Enum. Because a class can only extend one parent (see Declaring Classes), the Java language does not support multiple inheritance of state (see Multiple Inheritance of State, Implementation, and Type), and therefore an enum cannot extend anything else.

原来,这个枚举实际上是由java.lang.Enum这个类实现的,在程序中定义的枚举类型,都会隐式继承此类。并且,由于java中的继承是单继承,所以我们定义的枚举就无法在继承其他类了。 


我们来验证一下上面所说的内容: 
首先在刚才的测试类(在此取名EnumTest)开头添加一行import:

import java.lang.Enum;
  • 1
  • 1

使用 Ctrl+左键 点击查看其源码,原来是这样一个类:

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {
            ......
        }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

查看这个类的实现,果然是没有values()方法的。 
接下来我们通过命令行进入到EnumTest.java文件所在目录,在此使用javac命令编译这个文件:

javac EnumTest.java
  • 1
  • 1

通过ls命令查看编译成功后目录中的文件,结果如下:

EnumTest$Directions.class
EnumTest.class
EnumTest.java
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

我们可以看到编译器已经为我们生成了EnumTest$Directions.class这样一个class文件。 
通过javap命令,反编译EnumTest$Directions.class查看其中的内容:

javap EnumTest\$Directions.class
  • 1
  • 1

结果是这样的:

Compiled from "EnumTest.java"
final class EnumTest$Directions extends java.lang.Enum<EnumTest$Directions> {
  public static final EnumTest$Directions NORTH;
  public static final EnumTest$Directions SOUTH;
  public static final EnumTest$Directions EAST;
  public static final EnumTest$Directions WEST;
  public static EnumTest$Directions[] values();    //编译器插入的方法
  public static EnumTest$Directions valueOf(java.lang.String);
  static {};
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

我们可以看到编译器已经自动为我们插入了values()方法了。

最后总结一下: 
1.java中的enum关键字背后实际是Enum这个类实现的。 
2.在我们编写自定义的enum时,其中是不含values方法的,再编译java文件时,java编译器会自动帮助我们生成这个方法。

目录
相关文章
|
2月前
|
Java
Java语言实现字母大小写转换的方法
Java提供了多种灵活的方法来处理字符串中的字母大小写转换。根据具体需求,可以选择适合的方法来实现。在大多数情况下,使用 String类或 Character类的方法已经足够。但是,在需要更复杂的逻辑或处理非常规字符集时,可以通过字符流或手动遍历字符串来实现更精细的控制。
257 18
|
2月前
|
Java 编译器 Go
【Java】(5)方法的概念、方法的调用、方法重载、构造方法的创建
Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建,在其他地方被引用方法的优点使程序变得更简短而清晰。有利于程序维护。可以提高程序开发的效率。提高了代码的重用性。方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。这种就属于驼峰写法下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。
215 4
|
2月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
315 5
|
3月前
|
算法 安全 Java
除了类,Java中的接口和方法也可以使用泛型吗?
除了类,Java中的接口和方法也可以使用泛型吗?
154 11
|
3月前
|
Java 开发者
Java 函数式编程全解析:静态方法引用、实例方法引用、特定类型方法引用与构造器引用实战教程
本文介绍Java 8函数式编程中的四种方法引用:静态、实例、特定类型及构造器引用,通过简洁示例演示其用法,帮助开发者提升代码可读性与简洁性。
|
4月前
|
算法 Java
Java语言实现链表反转的方法
这种反转方法不需要使用额外的存储空间,因此空间复杂度为,它只需要遍历一次链表,所以时间复杂度为,其中为链表的长度。这使得这种反转链表的方法既高效又实用。
427 0
|
4月前
|
存储 Java 数据处理
Java映射操作:深入Map.getOrDefault与MapUtils方法
结合 `getOrDefault`方法的简洁性及 `MapUtils`的丰富功能,Java的映射操作变得既灵活又高效。合理地使用这些工具能够显著提高数据处理的速度和质量。开发人员可以根据具体的应用场景选择适宜的方法,以求在性能和可读性之间找到最佳平衡。
200 0
|
2月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
193 1
|
2月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
215 1
|
3月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案