[英]Why does Java allow null value to be assigned to an Enum?
這更像是一個設計問題,所以沒有代碼。 如果您希望我這樣做,我可以發布創建 Enum 並將其分配給null
代碼。 :))
我最近一直在思考這個問題,但想不出一個很好的理由。 Enum 常量是隱式的static和final 。 Enum 的意思是 - “我可以取一個存在於我中的常量的值”。 為什么允許 Enum 具有null
值? 為什么不將 Enum 的值隱式默認為Enum.DEFAULT
或Enum.None
? 這不是比允許 Enum 為null
更好的方法嗎?
首先, null
表示實例不存在。 提供像DEFAULT
或NONE
這樣的默認常量會改變這個含義。 其次,為什么你需要一些默認的東西來代表似乎不存在的東西? 這就是null
的目的。 基本上,您必須初始化並存儲一個額外的對象,該對象甚至不應該存在。
順便說一句,這不是語言選擇。 如何實現枚舉完全取決於您。 您可以在枚舉中提供另一個常量,如DEFAULT
或UNKNOWN
,並避免將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.