Reputation: 47
public class TestException extends except2 {
public static void main(String[] args)throws Exception {
try {
try {
throw new TestException();
}
catch (final TestException e){
}
throw new except2();
}
catch (TestException a){
}
catch (Exception e){
throw e;
}
}
public TestException(){
}
}
class except2 extends Exception{
}
Hi all,
my JDK version is 8u45 which is latest one now.
I'm wondering that is "precise rethrow with a final exception" still working in SE 8?
As the code, if I take the "throws Exception" off it'll be compilation error, but it should be able to be ignored according to "precise rethrow with a final exception" function of SE7.
Another question is that we all know if there's an exception happened in the nested try box, we should still throw it out to outer catch box to avoid compilation error, I originally figured that we only need to throw an exception of any types & it'll do, so is my test result, I think it's to let compiler know that there's an exception in try box & catch box got it, too.
but if I alter it like the following code:
public class TestException extends except2 {
public static void main(String[] args)throws Exception {
try {
try {
throw new ArithmeticException();
} catch (final TestException e){
throw e;
}
} catch (TestException a){
} catch (Exception e){
throw e;
}
}
}
the (final TestException e)
part will be compilation error with the message:
"the Exception "com.xxx.TestException" is never thrown in the corresponding try block",
and I'm confused because if nested catch block can't handle the exception, it shall goes to outer.
Then if I throw an ArithmeticException
in the end of outer try block like this:
try {
try {
throw new TestException();
}
catch (final TestException e){
System.out.println("d");
}
throw new ArithmeticException();
}
catch (TestException a){
}
catch (Exception e){
throw e;
}
Same error to the outer catch box catch (TestException a){}
Why is that?
it should be caught by (Exception e)
block.
If I can't throw different types of exception from the first exception of nested try block, why could I throw except2 in the first paragraph of code?
Upvotes: 0
Views: 209
Reputation: 10433
This is Oracles example for the feature, and it still works with Java 8:
static class FirstException extends Exception { }
static class SecondException extends Exception { }
public void rethrowException(String exceptionName)
throws FirstExceptio, SecondException // Since J7 no "Exception" needed
{
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
} catch (Exception e) {
throw e; // effective final (i.e. not assigned)
}
}
This is described in the second half of this Oracle document. Your examples are all not really related to it. Especially not the one where you have a more specific and a general catch. This is explicitly mentioned in the document as not working.
Your first block would work if you use except2
(I renamed it to BaseException
) which is the more specific one like this:
public class TestException extends BaseException {
public static void main(String[] args) {
try {
try {
throw new TestException();
}
catch (final BaseException e){
throw e; // this is defined as BaseEx, will fail on Java 6
}
}
catch (TestException a){ // this knows that no BaseEx is expected
}
}
public TestException(){
}
}
class BaseException extends Exception { }
As you can see, the main() method does not need to throw Exception anymore since the second catch block was sufficient.
Upvotes: 2
Reputation: 280138
Your first piece of code can be shortened to
class TestException extends except2 throws Exception {
public static void main(String[] args) {
try {
throw new except2(); // this
} catch (TestException a) {
} catch (Exception e) {
throw e;
}
}
public TestException() {
}
}
class except2 extends Exception {
}
You're throwing an except2
. A TestException
is an except2
, but an except2
is not necessarily a TestException
. The first catch
block cannot handle the except2
exception. So the second one must. Since it further throws
that exception, and that exception is necessarily checked, you need to have a throws
clause.
Your second piece of code
class TestException extends except2 {
public static void main(String[] args) throws Exception {
try {
try {
throw new ArithmeticException();
} catch (final TestException e) { // nothing above throws a TestException
throw e;
}
} catch (TestException a) {
}
catch (Exception e) {
throw e;
}
}
}
Is trying to catch a TestException
in the nested try
block. But since TestException
is a checked exception, the compiler can and does check if it can be thrown in that block. In your case, it can't. So it complains that's it useless to try and catch it.
Finally, in your last snippet
class TestException extends except2 {
public static void main(String[] args) throws Exception {
try {
try {
throw new TestException();
} catch (final TestException e) {
System.out.println("d");
}
throw new ArithmeticException();
} catch (TestException a) {
} catch (Exception e) {
throw e;
}
}
}
You're throwing and catching a TestException
in the nested try-catch
statement. So you can reduce the code to
class TestException extends except2 {
public static void main(String[] args) throws Exception {
try {
throw new ArithmeticException();
} catch (TestException a) {
} catch (Exception e) {
throw e;
}
}
}
Which has the same issue as your second piece of code. There is no code path there that can throw a TestException
.
Regarding comments, and to simplify the second snippet, the error reduces to
class TestException extends except2 {
public static void main(String[] args) throws Exception {
try {
throw new ArithmeticException();
} catch (final TestException e) { // nothing above throws a TestException
throw e;
}
}
}
You have a catch(TestException)
but nothing throws a TestException
, so it's useless code which the compiler rejects.
From comments, this is the problem with your cases 2 and 3
// ignore everything around this
try {
// nothing in this block
// can throw a TestException
throw new ArithmeticException();
// this whole catch block is useless code
// Test Exception can never be thrown
} catch (final TestException e){
throw e;
}
// ignore everything around this
Upvotes: 1