Unhandled exception type Exception

后端 未结 2 1830
情书的邮戳
情书的邮戳 2021-01-28 01:17

This is a simplified class that describes my problem:

public class Main {

    enum Test{
        First(method()){ // Unhandled exception type Exception
                 


        
相关标签:
2条回答
  • 2021-01-28 01:54

    I don't think you want to be throwing a checked exception here (which is what Exception is). The reason: you're invoking the call of method inside of the constructor of Test. There's really not a clean way to deal with it.

    While the obvious choice here is to switch to RuntimeException, I want you to reconsider throwing the exception in the first place. Since your enum will only ever have First declared in it, does it really make sense for it to throw an exception when it's being instantiated? Personally, I don't think it does; whatever dangerous operation it's doing should be deferred until you want to invoke it, and then would you want to throw your exception.

    0 讨论(0)
  • 2021-01-28 02:08

    Yes. It is a compilation error.

    No. There is no special syntax to deal with this.

    I do not want to catch Exception in method.

    Unfortunately if you throw a checked exception, it has to be caught further up the call stack. That is a fundamental design principal for the Java language, and one that the compiler enforces strictly.

    In this, case there is no way to catch the checked exception. Hence, if you are going to call a method in enum constant parameter (as per your code), the method cannot throw a checked exception1.

    Here is a possible workaround, though this is probably a bad idea:

    public class Main {
    
        enum Test{
            First(methodCatchingException()){
                // ...
            };
    
            Test(Object obj){
                //...
            }
        }
    
        static Object method() throws Exception{
            // ...
            if (someCondition){
                throw new Exception();
            }
        }
    
        static Object methodCatchingException() {
            try {
                return method();
            } catch (Exception ex) {
                throw new SomeRuntimeException("the sky is falling!", ex);
            }
        }
    }
    

    Another way to look at this problem is to ask yourself what should happen with the exception if the compiler let you write that ... and an exception was thrown? Where would it go?

    • You can't catch it ... because the enum initialization is like a static initialization.
    • If the Java runtime completely ignored the thrown exception, that would be really bad.
    • If the Java runtime crashed, then the model of checked exceptions is broken.

    So, what this is saying to me is that the Java language design is right, the Java compiler is right ... and the real problem here is in your application design:

    • You should not be propagating a checked exception here. If an exception occurs in this context it is categorically NOT a recoverable error.

    • Maybe it is inadvisable to use an enum for this ... because of the potential for non-recoverable initialization errors.

    (Note that if this method call terminates due to an unchecked exception, it will turn it into an ExceptionInInitializerError. In addition, the JVM will mark the enum class as uninitializable, and will throw an NoClassDefFoundError if your application attempts to use it; e.g. via Class.forName(...).)


    I assume that Exception is used here for illustration purposes. It is a bad thing to declare methods as throws Exception or to throw new Exception(...)


    1 - I had a look at the JLS for something to back this up. As far as I can tell, the spec does not mention this situation. I'd have expected to see it listed in JLS 11.2.3. However, it is clear that a compiler cannot allow a checked exception to propagate at that point as it would "break" the model of how checked exceptions work.

    0 讨论(0)
提交回复
热议问题