2010-08-22 8 views
10

Làm thế nào tôi có thể ném ngoại lệ từ một hàm tạo enum? ví dụ:Làm thế nào để ném một ngoại lệ từ một nhà xây dựng enum?

public enum RLoader { 
    INSTANCE; 
    private RLoader() throws IOException { 
    .... 
    } 
} 

tạo ra lỗi

loại Unhandled ngoại lệ IOException

+6

Tại sao bạn muốn làm điều đó? Với tôi điều này nghe có vẻ giống như một sự lạm dụng của khái niệm enum. Các giá trị enum được coi là hằng số, mà việc tạo ra không phụ thuộc vào bất cứ thứ gì. Ngay cả khi kỹ thuật bạn _could_ làm điều đó (bằng cách ném một ngoại lệ không được kiểm soát thay vì một ngoại lệ), tôi sẽ đề nghị bạn sửa lại thiết kế của bạn. Nếu bạn đang cố gắng để thực hiện một Singleton thông qua enum này, nó là tốt hơn để thực hiện nó bằng tay như một lớp bình thường. –

+2

Tôi đang triển khai Singleton, nhưng làm thế nào để thực hiện nó bằng tay như một lớp bình thường sẽ tốt hơn? Tôi vẫn sẽ phải ném một ngoại lệ từ mã được gọi bởi một bộ khởi tạo tĩnh. Bạn có thể ném các ngoại lệ không được kiểm soát từ một hàm tạo enum. – tukushan

+0

có điều gì đó * icky * về việc loại trừ một ngoại lệ chỉ bằng cách truy cập một giá trị enum. Không quá tệ khi đó là phương thức getInstance() đơn lẻ. –

Trả lời

15

Bởi vì trường hợp được tạo ra trong một initializer tĩnh, ném ra một ExceptionInInitializerError để thay thế.

+5

Mặc dù đó là một giải pháp khả thi nhưng tôi không nghĩ rằng nó sẽ có ý nghĩa để giải quyết vấn đề theo cách đó. –

0

Kịch bản đó không thể hoạt động.

Bạn đang cố gắng ném một kiểm tra Exception từ hàm tạo.

Công cụ xây dựng này được gọi là khai báo nhập cảnh enum INSTANCE, vì vậy ngoại lệ đã kiểm tra không thể được xử lý chính xác. Ngoài ra nó là theo ý kiến ​​của tôi đó là phong cách xấu để ném ngoại lệ từ một nhà xây dựng, như một nhà xây dựng thường không nên làm bất kỳ công việc và đặc biệt là không tạo ra lỗi.

Ngoài ra nếu bạn muốn ném một số IOException Tôi giả sử rằng bạn muốn khởi tạo một cái gì đó từ một tệp, vì vậy bạn có lẽ nên xem xét bài viết này trên dynamic enums.

+3

Nếu đó là kiểu xấu để ném Ngoại lệ từ một hàm tạo, bạn sẽ làm gì khi một trong các đối số cho hàm tạo của bạn không hợp lệ và sẽ ngăn không cho lớp của bạn hoạt động? Tôi muốn thất bại nhanh chóng bằng cách ném một ngoại lệ để tôi có thể nhận được một dấu vết ngăn xếp có ý nghĩa.Điều đó đang được nói, tôi đồng ý với bạn rằng OP không nên cố gắng để ném một ngoại lệ trong một constructor ** enum **. –

+0

@Kirk Woll: Tôi thích sử dụng phương pháp nhà máy để đảm bảo tính hợp lệ của các thông số. Ngoài ra tôi chủ yếu tập trung vào các ngoại lệ đã kiểm tra, RuntimeException sẽ là một cách tốt hơn để báo hiệu lỗi xác minh IMO. –

+2

Độc quyền sử dụng các phương pháp nhà máy cho tất cả các đối tượng instantiation? Oh nhà điều hành ** mới ** tồi tàn. :) –

3

Tôi có trường hợp tôi muốn sử dụng enums làm khóa trong một số lớp cài đặt. Cơ sở dữ liệu sẽ lưu trữ một giá trị chuỗi, cho phép chúng ta thay đổi hằng số enum mà không cần phải udpate cơ sở dữ liệu (một chút xấu xí, tôi biết). Tôi muốn ném một ngoại lệ thời gian chạy trong constructor của enum như một cách để cảnh sát độ dài của đối số chuỗi để tránh nhấn cơ sở dữ liệu và sau đó nhận được một sự vi phạm ràng buộc khi tôi có thể dễ dàng phát hiện ra nó.

public enum GlobalSettingKey { 
    EXAMPLE("example"); 

    private String value; 

    private GlobalSettingKey(String value) { 
     if (value.length() > 200) { 
      throw new IllegalArgumentException("you can't do that"); 
     } 
     this.value = value; 
    } 

    @Override 
    public String toString() { 
     return value; 
    } 
} 

Khi tôi tạo thử nghiệm nhanh cho điều này, tôi thấy rằng ngoại lệ được ném không phải của tôi, mà thay vào đó là ExceptionInInitializerError.

Có thể điều này thật ngu ngốc, nhưng tôi nghĩ đó là một kịch bản khá hợp lệ khi muốn ném một ngoại lệ vào bộ khởi tạo tĩnh.

+2

Nhưng ngoại lệ ban đầu là xích với ExceptionInInitializerError, vì vậy nếu bạn gọi 'getCause()' trên đó, bạn sẽ nhận được ngoại lệ ban đầu. – shrini1000