开发者

Ambiguity in where exception is caught

开发者 https://www.devze.com 2023-03-01 20:15 出处:网络
In the below code, where will the thrown Exception be caught? public interface MyInterface { public void execute() throws Exception;

In the below code, where will the thrown Exception be caught?

public interface MyInterface {
    public void execute() throws Exception;
}

public class MyImplementor implements MyInterface {
    publ开发者_Python百科ic void execute() throws Exception {
        throw new MyException();
    }
}

public class MyMainClass {
    public static void main(String args[]) {
        try {
            MyImplementor temp = new MyImplementor();
            temp.execute();
        } catch(MyException e) {
            sysout("MyException");
        } catch(Exception e) {
            sysout("Exception");
        }
    }
}

(MyException is a class extending Exception)

So where is this exception caught? Also, what is the logic used by the compiler to decide where it is caught?

If I placed the

catch(Exception e)

before the

catch(IOException e)

would it change the flow of control?


So where is this exception caught?

In the first handler.

Also, what is the logic used by the compiler to decide where it is caught?

It is not the compiler that "decides" ...

The behavior is specified by the Java Language Specification section 11.3:

"When an exception is thrown, control is transferred from the code that caused the exception to the nearest dynamically-enclosing catch clause of a try statement (§14.20) that handles the exception."

(Emphasis added.)

In other words, the exception that is propagating is compared (using the equivalent of instanceof) against the exception type of each of the handlers, in the declared order of the handlers. The first one that matches the exception is executed.

If I placed the "catch(Exception e)" before the "catch(IOException e)" would it change the flow of control?

Yes. (Assuming that you meant MyException rather than IOException.) This is a direct logical consequence of the behavior described above.


What this means is that you should order the handlers with the handlers for the most specific exceptions first. Some Java compilers and code quality / bug detector tools will warn you if you get this wrong, but this is not a compilation error.


Its some what like the if...else if .If one condition is satisfied it will get out from the remaining conditions... In case of exceptions, catch(Exception e) satisfies all the kind of exceptions since it is the parent of all exceptions. So the exception is caught at the top level itself. The compiler won't allow this. So put catch according to the order of inheritance from bottom to top . Then only you can get the exception according to its type.


you can't do that. The sequence of the (checked-)Exceptions are according to inheritance sequence. You can not add your parent exception before an exception which's inherited from this parent. IDE complains and the code will not be compiled!

In your case if your code throws an IOException, that will catched in IOException catch block, before it reaches Exception catch block. In other cases, Exception- catch block will catch any other exceptions


In your code MyException is not defined but it should extend Exception or RuntimeException. It won't make any difference anyway, your program will print "MyException" as it is the type of exception thrown.


a) you can't reverse the order of the catch blocks. If you did, the block for IOException would become unreachable - an instance of IOException is also an instance of Exception, so the catch (Exception e) block would catch it and you'd never hit the catch (IOException e) block. The code would then not compile - unreachable code is not allowed.

b) since MyException extends Exception and not IOException, it will not ever be caught by the catch (IOException e) block. It will therefore be caught by the catch (Exception e) block.

UPDATE

You've now changed the question, so the answer is slightly different:

a) You still can't reverse the blocks.

b) Now that you've changed the first block to catch (MyException e), the thrown exception will be caught there. The procedure is, the compiler looks at each catch block. If the exception it's trying to handle is an instance of the exception being caught, that catch block is executed. If not, it proceeds to the next catch block. If there are no more catch blocks, execution is terminated abruptly (a term from the Java Language Specification).

0

精彩评论

暂无评论...
验证码 换一张
取 消