Java中的枚舉與values()方法


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

在這里,我們定義了一個名叫Directions的enum,它其中包含了四個方向。
接下來,我們寫一個簡單的main函數,僅僅是調用values()方法:

1 public static void main(String[] args) {
2     Directions.values();
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;

使用 Ctrl+左鍵 點擊查看其源碼,原來是這樣一個類:

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

查看這個類的實現,果然是沒有values()方法的。
接下來我們通過命令行進入到EnumTest.java文件所在目錄,在此使用javac命令編譯這個文件:

javac EnumTest.java

通過ls命令查看編譯成功后目錄中的文件,結果如下:

EnumTest$Directions.class

EnumTest.class

EnumTest.java

我們可以看到編譯器已經為我們生成了EnumTest$Directions.class這樣一個class文件。
通過javap命令,反編譯EnumTest$Directions.class查看其中的內容:

javap EnumTest\$Directions.class

結果是這樣的:

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

我們可以看到編譯器已經自動為我們插入了values()方法了。

最后總結一下:
1.java中的enum關鍵字背后實際是Enum這個類實現的。
2.在我們編寫自定義的enum時,其中是不含values方法的,再編譯java文件時,java編譯器會自動幫助我們生成這個方法。

 

參考鏈接:https://blog.csdn.net/ucxiii/article/details/48708455

https://blog.csdn.net/qq_31473465/article/details/89574554


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM