Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I've read It isn't a best practice to handle multiple Exceptions like this:

public void myMethod() throws ExceptionA, ExceptionB, ExceptionC {
    //more code here
}

And then to call myMethod():

try {
    myObject.myMethod();
} catch(Exception e) {
    //More code here
}

Despite Exception is the parent class of all the other exceptions, it is consider a bad practice. But, in my application I'm using java SE 6 and I need to:

  • Do File operations that can imply a FileNotFOundException and IOException
  • Marshal objects (in order to create XML files) JAXBException
  • Create a pdf file (using pdfbox library) COSVisitorException
  • Send an email using JavaMail, MessagingException

The easiest way is to add a throws statement in method declaration, but what could be the proper way to write the client method?

Is it OK to add 6 or 7 catch blocks to handle all the possible exceptions?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
127 views
Welcome To Ask or Share your Answers For Others

1 Answer

Generally speaking (for Java 6 and below), you should handle each exception individually...

try {
    myObject.myMethod();
} catch (ExceptionA e) {
    // Condition for A
} catch (ExceptionB e) {
    // Condition for B
} catch (ExceptionC e) {
    // Condition for C
}

This allows you to handle each exception differently based on what it is, but also means you are only handling those exceptions reported to be thrown by the method

In Java 7+ you can make use of "multi-catch" or "combined catch" (we can't find an "official" term)

try {
    myObject.myMethod();
} catch (ExceptionA | ExceptionB | ExceptionC e) {
    // Condition for A and B and C
}

But even then, you should be focusing exceptions into "common" use groups

try {
    myObject.myMethod();
} catch (ExceptionA | ExceptionB e) {
    // Condition for A and B
} catch (ExceptionC e) {
    // Condition for C
}

Another option, if you control how the exceptions are defined, is to extend from a common base exception, a good example of this is the FileNotFoundException which extends from the IOException, which is thrown by FileReader and FileInputStream (as examples), this means you can handle the FileNotFoundException as a common IOException should you wish...

FileReader fr = null;
try {
    fr = new FileReader(new File(...));
    // Read from reader...
} catch (IOException exp) {
    // Common catch block
} finally {
    // Best attempt to close
    try {
        fr.close();
    } catch (Exception exp) {
    }
}

Or you could handle the FileNotFoundException as it's own condition...

FileReader fr = null;
try {
    fr = new FileReader(new File(...));
    // Read from reader...
} catch (FileNotFoundException exp) {
    // File not found condition
} catch (IOException exp) {
    // Other IO condition
} finally {
    // Best attempt to close
    try {
        if (fr != null) {
            fr.close();
        }
    } catch (Exception exp) {
    }
}

This allows you to either group "like" exceptions together, but also provides you with the control to define more fine grained conditions should you need to...

Beware though, we the above example, if I put the IOException first, the FileNotFoundException would never be handled, when doing this, make sure that you use the lowest/tightest/finest exceptions first, as they are processed sequentially in the order you have listed

Another option (which I'm not keen on, but have seen) might be to catch a "common" ancestor and then compare the actual type, which would allow you to provide common handlers for some sub-type of the exception.

} catch (IOException exp) {
    if (exp instanceof FileNotFound || exp instanceof FileSystemException) {   
        // Common handling
    } else {
        // Generic handling
    }
}

This might be helpful in situations where the method only throws the ancestor type (ie IOException), but you need to provide a more fine grained resolution

But, again, I would be focused on only handling the expected "common" exceptions declared as been thrown, don't be tempered to catch Throwable for example


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...