I think Exception.fillInStackTrace should return Exception or derived Exception objects. Considering the two functions below,
public static void f() throws Throwable {
try {
throw new Throwable();
} catch (Exception e) {
System.out.println("catch exception e");
e.printStackTrace();
}
}
public static void g() throws Throwable {
try {
try {
throw new Exception("exception");
} catch (Exception e) {
System.out.println("inner exception handler");
throw e.fillInStackTrace();
}
} catch (Exception e) {
System.out.println("outer exception handler");
e.printStackTrace();
}
}
- The
exception handlercould not catch thenew Throwable()in the first functionf(). - The
exception handlercould catch thee.fillInstackTrace()in the second functiong(). - But the second function
g()would still need tothrows Throwable. This is really strange, since we could catche.fillInstackTrace().
So my question is why doesn’t Exception.fillInStackTrace return Exception or Exception-derived instead of developing such a strange syntax?
EDIT:
To clarify my question: What I mean by “strange syntax” are
- Since
Exception.fillInStackTrace()returnThrowablereference,the exception handler which recieveExceptionreference should not be able to catch the exception.Because java does not allow implict downcast,it should be something likereturn (Exception)e.fillInstackTrace(). - Since it is designed that the exception handler recieving
Exceptionreference could handle theThrowableexception,there is no need to mark the methodg()throwsThrowableexception.But java compiler would enforce us to do so.
thanks.
It’s actually easier to answer your questions starting with question 2.
You asked:
2. Since it is designed that the exception handler recieving Exception reference could handle the Throwable exception,there is no need to mark the method g() throws Throwable exception.But java compiler would enforce us to do so.
Answer:
Actually, catch( Exception e) cannot catch a Throwable.
Try this:
You’ll see that the catch clause does not catch the throw in this case.
The reason that the catch clause works in your g() method is that when you invoke
throw e.fillInStackTrace(), the call to fillInStackTrace actually returns an Exception (that’s because e is an Exception itself). Since Exception is a subclass of Throwable, that does not contradict the declaration of fillInStackTrace.Now on to the first question
You asked:
1. Since Exception.fillInStackTrace() return Throwable reference,the exception handler which recieve Exception reference should not be able to catch the exception.Because java does not allow implict downcast,it should be something like return (Exception)e.fillInstackTrace().
Answer:
This is not exactly an implicit downcast. Think of this as a variation of overloading.
Let’s say you have
If you call
process(someObject), it will be determined at runtime whether the first or the second process method gets called. Similarly, whether or not the catch(Exception e) clause can catch your throw will be determined at runtime, based on whether you throw an Exception or Throwable.