Why does order matter when catching exceptions?

前端 未结 8 1278
闹比i
闹比i 2020-11-29 09:52

I had to answer this question with some code:

Suppose I wrote the following method specification:
public void manipulateData ( ) t

相关标签:
8条回答
  • 2020-11-29 10:26

    In Java you have to put the least inclusive Exception first. The next exceptions must be more inclusive (when they are related).

    For instance: if you put the most inclusive of all (Exception) first, the next ones will never be called. Code like this:

    try {
         System.out.println("Trying to prove a point");
         throw new java.sql.SqlDataException("Where will I show up?");
    }catch(Exception e){
         System.out.println("First catch");
    } catch(java.sql.SQLException e) {
         System.out.println("Second catch");
    }
    catch(java.sql.SQLDataException e) {
         System.out.println("Third catch");
    }
    

    will never print the message you'd expect it to print.

    0 讨论(0)
  • 2020-11-29 10:33

    Yes he is correct. As you can see in the Javadoc, SQLDataException is a subclass of SQLException. Therefore, your answer is wrong, since it would create a block of unreachable code in the second catch.

    In Java, this code would not even compile. In other languages (e.g. python) such code would create a subtle bug, because SQLDataException would actually be caught in the first block, and not in the second one (as would be the case if it was not a subclass).

    Had you answered catch(java.sql.SQLException | java.sql.SQLDataException e) { }, it would still be incorrect, since the question asks to handle each exception specifically.

    The correct answer is in Grijesh's answer

    0 讨论(0)
  • 2020-11-29 10:41

    Order matter when catching exceptions because of following reason:

    Remember:

    • A base class variable can also reference child class object.
    • e is a reference variable
    catch(ExceptionType e){
    }
    

    The lowercase character e is a reference to the thrown (and caught) ExceptionType object.

    Reason why your code not accepted?

    It is important to remember that exception subclass must come before any their superclasses. This is because a catch statement that uses a superclasses will catch exception of that type plus any of its subclasses. Thus, a subclass would never be reached if it came after its superclass.
    Further, in Java, Unreachable code is an error.

    SQLException is supperclass of SQLDataException

       +----+----+----+
       | SQLException |  `e` can reference SQLException as well as SQLDataException
       +----+----+----+
              ^
              |
              |
    +----+----+----+---+
    | SQLDataException |   More specific 
    +----+----+----+---+
    

    And if your write like having error Unreachable code (read comments):

    try{
    
    } 
    catch(java.sql.SQLException e){//also catch exception of SQLDataException type 
    
    }
    catch(java.sql.SQLDataException e){//hence this remains Unreachable code
    
    }
    

    If you try to compile this program, you will receive an error message stating that the first catch statement will handle all SQLException-based errors, including SQLDataException. This means that the second catch statement will never execute.

    Correct Solution?

    To fix it reverse the order of the catch statements.That is following:

    try{
    
    } 
    catch(java.sql.SQLDataException e){
    
    }catch(java.sql.SQLException e){
    
    }
    
    0 讨论(0)
  • 2020-11-29 10:47

    For compiler multiple catch statements are like if..else if..else if..

    So, from the point where compiler can map the generated exception (directly or by implicit type conversion), it will not execute subsequent catch statements.

    To avoid this implicit type conversion you should keep the more generic exception at last. More derived should be stated at the beginning of he catch statements and most generic should go at the last catch statements.

    SQLDataException is derived from SQLException which is interns deiced from Exception. So, you will not be able to execute any code written in catch(java.sql.SQLDataException e){} this block. Compiler even flags for that situation that its a dead code and will not be executed.

    0 讨论(0)
  • 2020-11-29 10:48

    Think of the inheritance hierarchies of the Exceptions: SQLDataException extends SQLException So if you catch the 'generic' one first (i.e. the topmost base-class of the hierarchy) then every thing 'below' it is of the same type due to polymorphism i.e., SQLDataException isa SQLException

    Thus you should capture them in bottom up order w.r.t. the inheritance hierarchy i.e., subclasses first all the way to (generic) base class. This is so because the catch clauses are evaluated in the order you've declared them.

    0 讨论(0)
  • 2020-11-29 10:50

    SQLDataException will never be hit as SQLException will catch any SQL exceptions before they reach SQLDataException.

    SQLDataException is a sub-class of SQLException

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