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编译器会自动帮助我们生成这个方法。

目录
相关文章
|
7天前
|
运维 Java 程序员
Java中的异常处理方法
本文深入剖析Java异常处理机制,介绍可检查异常、运行时异常和错误的区别与处理方式。通过最佳实践方法,如使用合适的异常类型、声明精确异常、try-with-resources语句块、记录异常信息等,帮助开发者提高代码的可靠性、可读性和可维护性。良好的异常处理能保证程序稳定运行,避免资源泄漏和潜在问题。
|
7天前
|
传感器 监控 Java
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
27 5
|
26天前
|
存储 安全 算法
Java容器及其常用方法汇总
Java Collections框架提供了丰富的接口和实现类,用于管理和操作集合数据。
Java容器及其常用方法汇总
|
1月前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
95 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
26天前
|
Java API
java.time常用方法汇总
`java.time` API 是从 Java 8 开始引入的时间日期处理库,旨在替代老旧的 `java.util.Date` 和 `Calendar`。它提供了更简洁、强大和灵活的方式处理日期、时间、时区及时间间隔,支持全球化和时间计算需求。API 包含获取当前时间、创建指定时间、解析和格式化字符串、进行加减运算、比较时间、获取年月日时分秒、计算时间间隔、时区转换以及判断闰年等功能。示例代码展示了如何使用这些功能,极大简化了开发中的时间处理任务。
|
2月前
|
Java
Java快速入门之类、对象、方法
本文简要介绍了Java快速入门中的类、对象和方法。首先,解释了类和对象的概念,类是对象的抽象,对象是类的具体实例。接着,阐述了类的定义和组成,包括属性和行为,并展示了如何创建和使用对象。然后,讨论了成员变量与局部变量的区别,强调了封装的重要性,通过`private`关键字隐藏数据并提供`get/set`方法访问。最后,介绍了构造方法的定义和重载,以及标准类的制作规范,帮助初学者理解如何构建完整的Java类。
|
2月前
|
Java 程序员 调度
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
84 9
|
Java
JAVA方法的定义
JAVA方法的定义
120 0
|
9月前
|
安全 Java 编译器
杭州 【Java基础知识 11】java泛型方法的定义和使用(学习+改进+自己理解,想法) (借鉴-侵-删)
杭州 【Java基础知识 11】java泛型方法的定义和使用(学习+改进+自己理解,想法) (借鉴-侵-删)
65 1
|
10月前
|
存储 Java
Java数组与带参数方法:定义、调用及实践
Java数组与带参数方法:定义、调用及实践
100 1

热门文章

最新文章