简体   繁体   中英

Java casting an exception (not class cast exception)

When an exception is caught in java is there a use case for casting the exception to a new type? Or is the standard

    throw new DiffException(e)

The only way to do it. I apologize if I'm overlooking something but the only search results I get are for "ClassCastExceptions" Which is obviously not what I'm looking for

I believe you meant 'exception wrapping' . There's no other way to do it - you create a new instance of Exception using a constructor which takes another exception as cause. This works thanks to 1-arg constructor of java.lang.Exception . The typical implementation of custom exception type (like your DiffException ) declares such 1-arg constructor too.

Well, if the exception caught ( e in your case I suppose) is a subtype of DiffException , you could of course cast it like

throw (DiffException) e;

but I doubt that's what you want to do, since it doesn't make a difference (the e will still have the same runtime type, even in the receiving end).

So the answer is most likely, no , there is no other, equivalent way, of doing

throw new DiffException(e);

than doing just that.

It should be noted however, that doing new DiffException(e) is not called casting but, wrapping , or chaining the exception.

Since you mentioned use cases, the common one in Java is wrapping a checked exception as unchecked; this is appropriate when there's no way the checked exception can occur, such as here:

public static Reader getUTF8Reader(InputStream is) {
    try {
        return new InputStreamReader(inputStream, "UTF-8");
    } catch(UnsupportedEncodingException e) {
        // should never happen since UTF-8 is guaranteed to be available as per
        // http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html
        throw new RuntimeException("UTF-8 not available", e);
    }
}

Without wrapping the exception, you'd either have to swallow it (which feels wrong) or declare the method as throws UnsupportedEncodingException which forces anyone using it to catch the exception that will never be thrown . Wrapping it, there's no onus on the caller to handle unlikely cases, yet we're protected in the unlikely event that UTF-8 isn't available on some obscure platform in the future.

If I understand you correctly here is the use case I am thinking about. expression:

new FileInputStream("the path");

may throw FileNotFoundException if the file does not exist. FileNotFoundException extends IOException , so you could write code like:

public void readFromFile(String path) {
    InputStream in = new FileInputStream(path);
    // do something....
}

Now you can call this method as following:

try {
    readFromFile("myFile");
} catch (IOException e) {
    if (e instanceof FileNotFoundException) {
        FileNotFoundException fnfe = (FileNotFoundException)e;
        // do something
    }
    // do something else
}

But I'd recommend you create separate catch blocks for FileNotFoundException and for IOException (at least for this use-case):

try {
    readFromFile("myFile");
} catch (FileNotFoundException e) {
    // do something with FileNotFoundException
} catch (IOException e) {
    // do something with IOException
}

This code does not contain instanceof, casting and other ugly stuff.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM