3 回答

TA貢獻1893條經驗 獲得超10個贊
Java強制使用枚舉開關的方法的默認返回語句覆蓋所有枚舉值......這種行為背后的設計決策是什么?
這是語言做出的一個非常重要(且正確)的決定。盡管您當前的代碼處理了枚舉的所有當前值,但這并不意味著在您的代碼編譯后很長時間內枚舉類可能會發生變化。您可能會升級第 3 方庫,它可能會添加另一個枚舉值,導致您的代碼在沒有默認值的情況下在運行時無效。
即使您控制了枚舉代碼,也不意味著其他開發人員(或未來的您)可能會向枚舉添加另一個值并且無法更新 switch 語句。以這種方式編寫向前兼容的代碼通常是最佳實踐,在這種情況下,對于語言強制行為至關重要。
我不知道回到這里做什么。
然后問題歸結為是否拋出異常。如何處理無效的枚舉值或其他異常情況是我們程序員每天都在努力的事情。在這種情況下,你需要問問自己你想要發生什么?這是不應該拋出的煩惱還是更嚴重的錯誤?調用者應該處理異常還是可以RuntimeException?這些是您需要在應用程序上下文中回答的問題。
最后,我不了解您,但我認識的大多數程序員都剪切并粘貼了大量代碼。雖然這個枚舉可能永遠不會被擴展,但未來的枚舉將會被擴展,做出正確的決定可能會受益于適當處理這種情況。
在這種情況下,強制使用默認的 return 語句是不舒服的......
"Unknown type" 可能是個不錯的選擇。
case ...:
return ...;
default:
// here in case someone updates the enum and forgets to update this code
return "Unknown type";
在這種情況下拋出異常在這里也沒有意義。
這在一定程度上取決于返回默認"unknown"字符串的交易有多大。如果有一個缺少 case 條目的新枚舉,您是否希望它拋出異常?
對于例外情況,您可能需要使用:
case ...:
return ...;
default:
throw new IllegalStateException("unknown enum type found for" + mType);
或者也許IllegalArgumentException。

TA貢獻1803條經驗 獲得超3個贊
如果稍后編輯枚舉,添加新常量,而不重新編譯開關,會發生什么情況?這就是要防范的情況。
寫 是完全正常的default: throw new AssertionError();
。

TA貢獻1860條經驗 獲得超9個贊
在這種情況下拋出異常在這里也沒有意義。
這是有道理的,因為即使您知道/認為您永遠不會進入這里,您也必須處理這種情況,以使您的代碼符合 Java 編譯規則,即期望該方法String在任何情況下都返回 a 。
您可以避免異常拋出,但它會使您的代碼不那么健壯:
String getMessageForType(MessageType myType) {
switch(myType) {
case error:
return "Error type";
case warning:
return "Warning type";
}
return "Info type";
}
假設fine添加了一個枚舉值并且您沒有更新,getMessageForType()您將返回“信息類型”而不是。
所以這是一個很好的方法:
String getMessageForType(MessageType myType) {
switch(myType) {
case error:
return "Error type";
case warning:
return "Warning type";
case info:
return "Info type";
}
throw new RuntimeException("Should not happen here ! We get the enum value " + myType);
}
更好的方法是將String關聯添加到每個枚舉作為枚舉的實例字段:
enum MessageType {
ERROR("Error type"), WARNING("Warning type"), INFO("Info type");
private String msg;
MessageType(String msg){
this.msg = msg;
}
public String getMsg(){
return msg;
}
}
通過這種方式,您不再需要 theswitch以及getMessageForType()方法。
該shouldReturnStringForEnum()方法可以很簡單:
@Test
public void shouldReturnStringForEnum() {
System.out.println(getType().getMsg());
}
添加回答
舉報