Are multiply-thrown Exceptions checked or runtime?
I have an Exception chain in which method1
throws an Exception to method2
which throws the Exception on to main
. For some reason, the compiler forces me to deal with the error in method2
and marks it as an error if I don't, indicating that it's a checked Exception. But when the same Exception
is thrown further down the line to main
, the compiler allows me to ignore it and doesn't display any errors.
The original Exception in method1
is a ParseException
, which is checked. But the method has a generic throws Exception
clause in the header, and the same object is thrown to method2, which has an identical throws Exception
clause. When and how does this Exception lose the status of being checked / caught by the compiler?
Edited to clarify:
public void method1() throws Exception{
// code that may generate ParseException
}
public void method2() throws Exception{
method1(); //compiler error (if the throws clause is left out)
}
public static void main(String[] args){
method2(); //ignored by compiler, even though the exception isn't caught or thrown or handled at all
}
开发者_StackOverflow
Edit:
Sorry everyone, the question was based on a mistake... The main method actually had a throws Exception
clause that I was missing. I've removed that and the code is now behaving as expected. Thanks for all the help!
Whether an exception is checked or not is entirely dependent on what kind of exception it is: If it's a RuntimeException
or a subclass of it, it's not checked; otherwise, it is. (And yes, RuntimeException
is a subclass of Exception
— one of the failures of the Java library design, but not the most major.)
What the compiler checks is the method signatures. So the actual exception thrown is irrelevant (for this purpose). If the methods say throws Exception
then you have to catch Exception
in your method or declare that the method throws Exception
. Methods should always use the narrowest possible throws
clause — e.g., not throws Exception
but throws ParseException
.
(I say "irrelevant (for this purpose)" because, of course, one of the other things the compiler will do is check that you don't throw checked exceptions that aren't covered by your throws
clause.)
Edit The code you added in your edit won't compile: 1. It's calling an instance method without an instance, and 2. main
needs to declare that it throws Exception
.
This code solves the other problems, and (correctly) demonstrates that main
needs the throws Exception
clause:
public class CheckTest
{
public static final void main(String[] params)
{
new CheckTest().method2();
}
public void method1() throws Exception{
throw new java.text.ParseException("foo", 2);
}
public void method2() throws Exception{
this.method1();
}
}
Result:
CheckTest.java:27: unreported exception java.lang.Exception; must be caught or declared to be thrown
new CheckTest().method2();
^
1 error
A checked exception does not stop being a checked exception. The way you can sort of turn a checked exception into unchecked is by wrapping it inside a type of RuntimeException and re-throwing it.
In your case, it'll be Exception
s all the way down to the root of the call stack. If a method is declared to throw Exception
(which methods very seldom should do), the calling method will either have to say it throws Exception
too, or catch it and deal with it.
Edit As for the example in the edited OP, that won't compile. You can declare main
to throw Exception
if you don't want to deal with it, though.
Is it possible that your compiler is not complaining about the issue in main()
because it hits the issue in method2()
and stops checking the syntax at that point? Both should be an error. Have you fixed the call in method2()
and gotten a clean compile?
精彩评论