2011-09-05 55 views
7

我正在嘗試檢查用戶傳遞的值是否爲有效常量。這是我寫的代碼。使用異常驗證輸入

enum Media_Delivery { 
    Streaming, Progressive 
} 

public class TestMain { 
    public static void main(String[] args) { 
     String medi_delivery = "streaming"; 
     try { 
      Media_Delivery.valueOf("streaming"); 
     } catch (IllegalArgumentException e) { 
      System.out.print(e); 
     } 

    } 

} 

現在,在上面的代碼中,如果通過未withing列出的枚舉字符串然後它拋出IllegalArgumentException這是顯而易見的。

但我的問題是:這是驗證的正確方法嗎?因爲我們正在使用Java的異常機制來驗證。

有人可以提出一個更好的主意,或者我上面編碼的是最好的選擇嗎?

-----編輯--------

,我想討論另一種情況:



    public class TestMain { 
      public static void main(String[] args) { 
       String inputPassed = "2a"; 
       try { 
        Integer.parseInt(inputPassed); 
       } catch (NumberFormatException nfe) { 
        throw new SomeUserDefinedException("Please enter only numeric values"); 
       } 

      } 

所以這是一個好主意嗎?或者應該有我們自己的解析機制?

+1

通常它被認爲是不好的做法,使用異常「代碼向例外」,換句話說,以確定邏輯。看看@Chris建議的內容。 –

回答

1

我想說這取決於。

如果輸入來自GUI元素(如組合框或任何其他),只有枚舉值可供選擇 - 那麼您的方法是可以的。這裏不同的價值確實是一個例外。

但是,如果您正在製作控制檯應用程序或textfiled輸入任何內容然後結果不同,那麼不應將枚舉值視爲異常。您應該使用正常的if-else或使用此方法的情況。

一般情況下:只對特殊情況使用異常,而不適用於真正可以發生的事情。

2

通常情況下,最好的做法不是抓住或拋出未檢查的表達式(IllegalArgumentExceptionRuntimeException,它被視爲「未選中」)。有關更多詳細信息,請參見the Java Tutorials - Exceptions。如果可以避免它,請嘗試重寫代碼,以免發生運行時異常。這是一個有爭議的問題,但運行時異常的存在是有原因的:它們幫助程序員識別錯誤。如果你抓住它們,那麼這個錯誤就不會被修復,它只是被避免。嘗試使用if-else語句?

根據the API,「名稱必須完全匹配用於聲明枚舉常量的標識符。」我相信這意味着參數是區分大小寫。另外,valueOf方法的返回類型是某種類型,而不是void,因此在try塊中不能包含該語句。 try塊應包含命令或void方法,例如int x = 3;System.out.println(3);或其他。

-------- -------編輯

OP,響應您的評論:

與其他人一樣在這裏說,這取決於你想要什麼去完成。我假設,因爲您的try塊中有Media_Delivery.valueOf("streaming");行,您試圖查看"streaming"是否等於枚舉常量之一?在這種情況下,你不會需要一個if-else語句,你可以簡單地寫

boolean result = medi_delivery.equals(Media_Delivery.Streaming.name()) || 
    medi_delivery.equals(Media_Delivery.Progressive.name()); 
System.out.println(result); 

甚至更​​好,如果你不想有多個||條件,嘗試switch聲明,通過每個週期枚舉常量,測試給定字符串的相等性。

克里斯

PS:在命名慣例,因爲枚舉常量是隱含static final,通常的做法是宣佈他們全部大寫,如STREAMINGPROGRESSIVEthe Java Tutorials - Enums)。

+0

咦?您可以忽略try catch塊中的返回對象,就像您可以在代碼中的任何其他位置一樣。無論它是一個好主意還是一個單獨的主題,還是一個取決於程序員正在努力完成的主題。 – user439407

+0

那麼testSubject528491如何用if-else完成上面的任務?你可以請一些示例代碼。 –

+1

非常感謝Chris的建議和回答。 –

1

沒有單一的「正確」方式來驗證,你有什麼肯定會是我會驗證的方式,但也有其他方法(例如,你可以把枚舉的所有有效字符串值放在HashSet中,然後檢查該集合是否有效,這可能是valueOf方法的反作用)

現在,如果上述方法是「更好」或不是,那也是相當主觀的。如果您正在循環中進行驗證,並且想要拒絕包含無效數據的任何內容,那麼異常方法可能是最好的。如果你想標記所有不合適的元素,那麼兩種方法都可以工作......如果存在大量有問題的數據,HashSet可能會更快,因爲你不必生成大量新的異常對象,但即使如此,性能幾乎可以忽略不計。

+0

'性能'和'在這裏使用或不使用異常'是兩個非常獨立的主題;) – dantuch

8

例外應該用於特殊情況;你不希望發生的事情。驗證輸入不是非常特殊。

Josh Bloch在他的書「有效的Java」中特別提到了這一點,即每個Java程序員應該擁有的IMHO。

編輯:這實際上是一個很好的答案,如何來解決這個問題:

Check valid enum values before using enum