簡體   English   中英

為什么 Java 允許將空值分配給 Enum?

[英]Why does Java allow null value to be assigned to an Enum?

這更像是一個設計問題,所以沒有代碼。 如果您希望我這樣做,我可以發布創建 Enum 並將其分配給null代碼。 :))

我最近一直在思考這個問題,但想不出一個很好的理由。 Enum 常量是隱式的staticfinal Enum 的意思是 - “我可以取一個存在於我中的常量的值”。 為什么允許 Enum 具有null值? 為什么不將 Enum 的值隱式默認為Enum.DEFAULTEnum.None 這不是比允許 Enum 為null更好的方法嗎?

首先, null表示實例不存在。 提供像DEFAULTNONE這樣的默認常量會改變這個含義。 其次,為什么你需要一些默認的東西來代表似乎不存在的東西? 這就是null的目的。 基本上,您必須初始化並存儲一個額外的對象,該對象甚至不應該存在。

順便說一句,這不是語言選擇。 如何實現枚舉完全取決於您。 您可以在枚舉中提供另一個常量,如DEFAULTUNKNOWN ,並避免將null分配給代碼中的引用。 這就是眾所周知的空對象模式 但是說null賦值本身應該是編譯器錯誤,那么我會說,因為無論如何Enum被編譯為Class ,所以使用null來表示實例的不存在是完全有效的。

允許null一個陷阱是在switch-case使用enum 即使使用default情況,以下代碼也會拋出NPE

public class Demo {
    enum Color {
        WHITE, BLACK;
    }

    public static void main(String[] args) {
        Color color = null;

        switch (color) {    // NPE here
        case WHITE: break;
        case BLACK: break;
        default: break;     // null value does not fall into the default
        }
    }
}

Java 不允許case null:或者,產生以下編譯錯誤:

枚舉 switch case 標簽必須是枚舉常量的非限定名稱

Java 允許任何引用為空,並且對枚舉的引用並沒有那么特殊,以至於需要進行特殊情況來阻止它,或者提供已經明確指定和易於理解的另一個版本的行為。 Null 已經是一個完全足夠的哨兵值:我們不需要另一個。

您的建議都沒有說服力,因為它們都需要添加更多功能來支持它們。

無論如何,現在開始辯論這個問題已經晚了幾年。

我認為, Enum.DEFAULT意味着您的 enum 變量包含一個值,但null不包含。 如果它為null則可以將其解釋為沒有值,例如,您不能在其上調用非靜態方法。

您可以向您的枚舉添加行為(域驅動設計),例如添加一個名為 prettyPrint() 的公共方法,該方法根據您的枚舉值返回一個字符串。 默認值/空值如何提供此自定義方法的實現?

如果您想用枚舉表示 null,那么您必須通過手動使用帶有 NONE 值的空對象模式和基於 NONE 值的 PrettyPrint() 自定義實現來明確這一點。

老了,我知道。 我是 Java 的一半。

為什么允許 Enum 具有空值?

我相信,用例很少。 例如,我們需要初始化一個 enum 變量來告訴我們它實際上不是 enum 的一部分,但是我們可以稍后更改它的值,使其成為它的一部分。 如果無法將枚舉變量初始化為null ,那么我們將污染枚舉定義。 因此,在我看來,諸如LibEnum.NONE字段會LibEnum.NONE庫。 例如,您不希望將LibEnum.NONE用作方法的參數,等等。

我發現它在我的詞法掃描器中很有用,包括關鍵字和標點符號。 假設您有一個標識符"blah" 然后你想檢查它是否是任何關鍵字。

private Keywordv getKeywordValue(String id)
{
    switch (id.length())
    {
        case 2:
        {
            switch (id)
            {
                case "do": return Keywordv.DO;
                case "if": return Keywordv.IF;
                case "is": return Keywordv.IS;

                // ...
            }

            break;
        }

        // ...
    }

    return null;
}

多虧了null ,很容易驗證標識符是否不是關鍵字。

id == null

否則我們必須定義類似Keywordv.__NULL東西

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM