2011-09-05 27 views
7

Tôi đang cố gắng kiểm tra xem giá trị được chuyển bởi người dùng có phải là hằng số hợp lệ hay không. Đây là mã tôi đã viết.Sử dụng Ngoại lệ để xác thực các đầu vào

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); 
     } 

    } 

} 

Bây giờ, ở trên mã nếu chuỗi được chuyển không khớp với enum được liệt kê thì nó sẽ hiển thị IllegalArgumentException rõ ràng.

Nhưng câu hỏi của tôi là: Đây có phải là cách thích hợp để xác thực không? Vì chúng tôi đang sử dụng cơ chế ngoại lệ của Java để xác thực.

Ai đó có thể đề xuất ý tưởng hay hơn hoặc những gì tôi đã mã hóa ở trên chính nó là tùy chọn tốt nhất?

----- EDIT --------

Một trường hợp khác mà tôi muốn thảo luận:



    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"); 
       } 

      } 

Vì vậy, đây là một ý tưởng tốt? Hoặc phải có cơ chế phân tích cú pháp của riêng chúng ta?

+1

Thông thường nó được coi là xấu thực hành để "mã đối với trường hợp ngoại lệ", hay nói cách khác sử dụng ngoại lệ đối với xác định logic. Hãy xem những gì @Chris đề xuất. –

Trả lời

1

Tôi muốn nói điều đó tùy thuộc.

Nếu đầu vào đến từ phần tử GUI như combobox hoặc bất kỳ thứ gì, trong đó giá trị enum là giá trị enum duy nhất để chọn - thì cách tiếp cận của bạn là ok. Ở đây giá trị khác nhau thực sự sẽ là một ngoại lệ.

Nhưng nếu bạn đang tạo ứng dụng giao diện điều khiển hoặc được textfiled với khả năng gõ bất cứ điều gì thì kết quả khác nhau thì giá trị enum không được coi là ngoại lệ. Bạn nên sử dụng bình thường nếu có hoặc các trường hợp với cách tiếp cận này.

nói chung: chỉ sử dụng trường hợp ngoại lệ cho các trường hợp ngoại lệ và không áp dụng cho điều gì đó thực sự dễ xảy ra.

2

Thực tiễn tốt nhất là không bắt hoặc ném các biểu thức không được kiểm soát (IllegalArgumentException là một số RuntimeException được tính là "không được chọn"). Xem the Java Tutorials - Exceptions để biết thêm chi tiết. Nếu bạn có thể tránh nó, hãy thử viết lại mã của bạn sao cho không cần phải có ngoại lệ thời gian chạy. Đây là một vấn đề gây tranh cãi, nhưng ngoại lệ thời gian chạy tồn tại vì một lý do: chúng giúp lập trình viên xác định lỗi. Nếu bạn bắt được chúng, thì lỗi đó không được sửa, nó chỉ là tránh được. Thử sử dụng câu lệnh if-else?

Theo the API, "tên phải khớp chính xác với số nhận dạng được sử dụng để khai báo hằng số enum." Tôi tin rằng điều này có nghĩa là thông số là phân biệt chữ hoa chữ thường. Ngoài ra, kiểu trả về của phương thức valueOf là một số loại, không phải là void, do đó bạn không thể có tuyên bố đó trong khối try. Các khối try phải chứa các lệnh hoặc các phương thức void, chẳng hạn như int x = 3; hoặc System.out.println(3); hoặc một thứ gì đó.

-------- EDIT -------

OP, để đáp ứng với nhận xét của bạn:

Giống như những người khác ở đây đã nói, nó phụ thuộc vào những gì bạn đang cố gắng để thực hiện. Tôi giả sử rằng vì bạn có dòng Media_Delivery.valueOf("streaming"); trong khối try, nên bạn đang cố gắng xem liệu "streaming" có bằng một trong các hằng số enum không?Trong trường hợp đó, bạn sẽ không cần một tuyên bố if-else, bạn chỉ có thể viết

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

Hoặc thậm chí tốt hơn, nếu bạn không muốn có nhiều || điều kiện, hãy thử một tuyên bố switch rằng chu kỳ qua từng enum hằng số, kiểm tra sự bình đẳng của chuỗi đã cho.

-Chris

PS: trên quy ước đặt tên, vì hằng enum là ngầm static final, đó là thực tế phổ biến để khai báo chúng trong tất cả mũ, chẳng hạn như STREAMINGPROGRESSIVE (the Java Tutorials - Enums).

+0

Huh? Bạn có thể bỏ qua các đối tượng được trả lại bên trong khối try try giống như bạn có thể ở bất kỳ nơi nào khác trong mã. Có hay không ý tưởng hay của nó là một chủ đề riêng biệt và một chủ đề sẽ phụ thuộc vào những gì người lập trình đang cố gắng thực hiện. – user439407

+0

Vậy testSubject528491 làm cách nào để hoàn thành nhiệm vụ ở trên với if-else? Bạn có thể vui lòng đặt một số mã mẫu. –

+1

Cảm ơn rất nhiều Chris đã đề xuất và trả lời của bạn. –

1

Không có cách "hợp lệ" để xác thực, điều bạn chắc chắn sẽ là cách tôi xác nhận, nhưng có nhiều cách khác (ví dụ bạn có thể đặt tất cả các giá trị chuỗi hợp lệ của liệt kê trong một HashSet và sau đó kiểm tra xem tập hợp đó có hợp lệ hay không, đó có thể là phương thức valueOf nào)

Bây giờ nếu cách tiếp cận trên là "tốt hơn" hay không thì điều đó cũng khá chủ quan. Nếu bạn đang thực hiện xác thực trong vòng lặp và muốn từ chối bất kỳ thứ gì chứa dữ liệu không hợp lệ, thì cách tiếp cận ngoại lệ có lẽ là tốt nhất. Nếu bạn muốn gắn cờ tất cả các phần tử không phù hợp thì phương pháp tiếp cận hoạt động .... HashSet có thể sẽ nhanh hơn nếu có nhiều dữ liệu có vấn đề khi bạn không phải tạo ra nhiều đối tượng ngoại lệ mới, nhưng thậm chí sau đó sự khác biệt trong hiệu suất sẽ khá đáng kể.

+0

'hiệu suất' và' sử dụng hoặc không sử dụng ngoại lệ ở đây' là hai chủ đề rất riêng biệt;) – dantuch

8

Ngoại lệ nên được sử dụng cho điều kiện đặc biệt; những điều bạn không mong đợi xảy ra. Xác thực đầu vào không phải là rất đặc biệt.

Josh Bloch thực sự vạch ra điều này đặc biệt trong cuốn sách 'Java hiệu quả' của mình mà IMHO là thứ mà mọi lập trình viên Java nên có.

EDIT: Và đây thực sự là một câu trả lời rất tốt để làm thế nào để tiếp cận vấn đề:

Check valid enum values before using enum

Các vấn đề liên quan