This question already has answers here:
Understanding checked vs unchecked exceptions in Java
(21 answers)
Closed 2 years ago.
Came across this piece of code: -
public <T> T call(final Callable<T> callable) {
try {
return callable.call();
} catch (Exception exception) {
if (exception instanceof RuntimeException) {
throw (RuntimeException) exception; // Line 6
} else {
throw new RuntimeException(exception); // Line 8
}
}
}
What is the need for doing a (RuntimeException) exception at line 6?
What is the difference between the exceptions being thrown at line 6 v/s line 8. Aren't they doing the same thing?
The code there is to transform a checked exception into a unchecked exception. In Java, checked exceptions have to be declared on a method with the throws keyword, while unchecked exceptions don't need to be declared on the method. Exception is the base class for all exceptions while RuntimeException (which is a subclass of Exception) is the base class for all unchecked exceptions.
The code on line 6 is to make the compiler happy. As Exception is a checked exception, by casting it to RuntimeException the compiler won't enforce the exception to be declared on the method with a throws. Line 8 wrapes the checked exception into a unchecked exception.
Related
Java allows me to compile the following code without any issues:
public class Test {
public static void main(String[] args){
try {
throw new RuntimeException();
} catch (Exception e) {
throw e;
}
}
}
Even though java.lang.Exception is a checked exception. Meaning that I am rethrowing unchecked exception as checked and get away with that.
Most likely Java compiler is able to figure out that no checked exception is thrown in the try block, but I can't find the section in the specification that backups that.
Can one rely on this behavior and starting from which JDK version?
Update:
This class doesn't compile with Java 1.6.0_38 with the following message:
Test.java:6: unreported exception java.lang.Exception; must be caught or declared to be thrown
throw e;
^
1 error
It looks like that this is one of the effects of the enhancement in Java 7: Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking. See section "Rethrowing Exceptions with More Inclusive Type Checking."
The Java SE 7 compiler can determine that the exception thrown by the statement throw e must have come from the try block, and the only exceptions thrown by the try block can be FirstException and SecondException. Even though the exception parameter of the catch clause, e, is type Exception, the compiler can determine that it is an instance of either FirstException or SecondException.
Please note, that the following will not compile though even in Java 7 and above:
public class Test {
public static void main(String[] args){
try {
throw new RuntimeException();
} catch (Exception e) {
Exception e1 = e;
throw e1;
}
}
}
Because:
This analysis is disabled if the catch parameter is assigned to another value in the catch block.
The part of the Java Language Specification that governs this can be found in JLS 11.2.2
11.2.2. Exception Analysis of Statements
...
A throw statement whose thrown expression is a final or effectively
final exception parameter of a catch clause C can throw an exception
class E iff:
E is an exception class that the try block of the try statement which declares C can throw; and
E is assignment compatible with any of C's catchable exception classes; and
E is not assignment compatible with any of the catchable exception classes of the catch clauses declared to the left of C in the same try
statement.
When E is RuntimeException 1) E can be thrown in the try block, 2) the catch clause can catch it, and 3) there are no catch clauses "to the left". Therefore the throw in the catch clause can throw RuntimeException.
On the other hand, E is Exception, E cannot be thrown in the try block. Therefore the throw in the catch clause cannot throw Exception.
Java docs explains clearly about object coherency while dealing with type-casting,return type of Over-riding method and throwing and catching Exceptions. But now i am little confused with Exceptions, What is the hidden concept behind this code..
void getNames() throws SQLClientInfoException { /*throws Subclass object to caller*/
try{
// throwing Subclass object to catch block but up-casting to Exception
throw new SQLClientInfoException();
} catch (Exception e) {
throw e; /* re-throwing throwing as Exception
}
}
Its a feature of programming language introduced in Java SE 7 - Use more precise re-throw in exceptions.
The Java SE 7 compiler performs more precise analysis of re-thrown exceptions than earlier releases of Java. This enables to specify more specific exception types in the throws clause of a method declaration.
Prior to Java 7:
void aMethod() throws CustomDbException {
try {
// code that throws SQLException
}
catch(SQLException ex) {
throw new CustomDbException();
}
}
Re-throwing an exception in the catch block need not indicate the
actual exceptions possible from the try block.
The type of exception thrown could not be changed without changing
the method signature.
In Java 7 or higher:
void aMethod() throws IOException {
try {
Files.copy(srcePath, trgtPath); // throws IOException
}
catch(Exception ex) {
throw ex;
}
}
The above code is legal in Java 7.
If an exception of some type is thrown in the try clause and is not assigned an exception variable in the catch clause, the compiler will copy over the checked exception type that can be thrown from the try block. (It is as if throwing all the exceptions possible from the try block provided that the exception variable is not reassigned).
The compiler knows that the only possible exception type is an IOException (because that is what the Files.copy() can throw).
Also, see this article at Oracle's website: Rethrowing Exceptions with More Inclusive Type Checking.
Because SQLClientInfoException is a subclass of "java.lang.Exception", it is caught by catch block when SQLClientInfoException is thrown
"e" variable in the catch block refers to SQLClientInfoException.
This question already has answers here:
Why is throwing a checked exception type allowed in this case?
(3 answers)
Closed 6 years ago.
Consider the following code:
static void main(String[] args) {
try {
} catch (Exception e) {
throw e;
}
}
This code compiles without having to add throws Exception to the method signature. (It behaves similarly with Throwable in place of Exception, too).
I understand why it can be run safely, in that Exception can't actually be thrown in the try block, so a checked exception cannot be thrown; I'm interested to know where this behaviour is specified.
It's not simply that the throw e is never reached: the following code also compiles:
static void stillCompilesWithThrownUncheckedException() {
try {
throw new NullPointerException();
} catch (Exception e) {
throw e;
}
}
But if you throw a checked exception, it doesn't compile, as I expect:
static void doesNotCompileWithThrownCheckedException() {
try {
throw new Exception();
} catch (Exception e) {
throw e; // error: unreported exception Exception; must be caught or declared to be thrown
}
}
In JLS Sec 11.2.2, it says:
A throw statement (§14.18) whose thrown expression has static type E and is not a final or effectively final exception parameter can throw E or any exception class that the thrown expression can throw.
My interpretation of this statement is that throw e can throw Exception, because the static type of e is Exception. And then, in JLS Sec 11.2.3:
It is a compile-time error if a method or constructor body can throw some exception class E when E is a checked exception class and E is not a subclass of some class declared in the throws clause of the method or constructor.
But it's not a compile-time error in the first two cases. Where is this behavior described in the language spec?
Edit: having marked it a dupe, I was going to ask the follow-up question: why isn't throw e; considered unreachable in the first example.
The answer was much easier to find in JLS Sec 14.21:
A catch block C is reachable iff both of the following are true:
Either the type of C's parameter is an unchecked exception type or Exception or a superclass of Exception, or some expression or throw statement in the try block is reachable and can throw a checked exception whose type is assignable to the type of C's parameter. (An expression is reachable iff the innermost statement containing it is reachable.)
See §15.6 for normal and abrupt completion of expressions.
There is no earlier catch block A in the try statement such that the type of C's parameter is the same as or a subclass of the type of A's parameter.
Both of these are true (it's of type Exception, and there's no earlier catch block), so it's "reachable". I guess the effort of calling out an empty try block as a special case was too great for such a marginally-useful construct.
I believe the very next paragraph of section 11.2.2 answers the question:
A throw statement whose thrown expression is a final or effectively final exception parameter of a catch clause C can throw an exception class E iff:
E is an exception class that the try block of the try statement which declares C can throw; and
…
So, throw e; “can throw” only exceptions which the corresponding try-block “can throw,” where the latter is defined by the actual statements in the try-block.
Obviously an empty try-block does not qualify as a “can throw” section for any exception class. Your second example “can throw” NullPointerException, and since the catch-block “can throw” only the exception that the try-block “can throw,” the catch-block too can throw only the unchecked NullPointerException.
Your third example’s try-block “can throw” java.lang.Exception itself, therefore the catch-block “can throw” java.lang.Exception, so java.lang.Exception must be caught or declared to be thrown.
This question already has answers here:
How to define custom exception class in Java, the easiest way?
(8 answers)
Closed 8 years ago.
I need to change the return message of the method getMessage() ,
for instance, i have an ArithmeticException, and when I write:
try{c=a/0;}
catch(ArithmeticException excep){System.out.println( excep.getMessage() );}
and I execut this code I have: / by zero.
So, I wanted to change this result by overwriting the getMesage method.
I have created a new class called MyException that inherits from ArithmeticExceprtion and I override the methode getMessage, and after that I have changed the type of the exception in my last code from ArithmeticException to my new name class MyException:
public class MyException extends ArithmeticException{
#override
public String getMessage(){
retun "new code message";}
}
and I have changed the first code, I have wrotten:
try{c=a/0;}
catch(MyException excep){System.out.println( excep.getMessage() );}
and when I have executed this code, I had the same error's message as if I didn't catch the exception:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at main.test.main(Test.java:33)
So, my question is: how can I change the message of the methode getMessage() ?
You have extended the ArithmeticException with a new class called MyException. But the statement c = a / 0; still throws ArithmeticException but never MyException itself, so your catch clause is not reached.
Note that normally you shouldn't catch runtime (unchecked) exceptions like ArithmeticException since it denotes a programming error. Also note that for checked exceptions, the compiler shows an error telling you that the statement would never throw that kind of exception, but in this case, MyException is an unchecked exception so the compiler is fine with it.
In your particular scenario, you cannot change the message of the exception since it will always be an ArithmeticException. But you can always print whatever message you want in the catch clause. Or you can wrap the statement in a method and let that method throw the subclass exception:
public void foo() throws MyException {
try {
c = a / 0;
} catch (ArithmeticException excep) {
// handle excep
throw new MyException();
}
}
This question already has answers here:
Exception handling : throw, throws and Throwable
(8 answers)
Closed 8 years ago.
Can any one clearly state the difference between throw and throws in Java exception handling with an example? I have tried googling but couldn't arrive at a conclusion. Pls help
throws clause is used to declare an exception and throw keyword is used to throw an exception explicitly.
If we see syntax wise then throw is followed by an instance variable and throws is followed by exception class names.
The keyword throw is used inside method body to invoke an exception and throws clause is used in method declaration (signature).
For example
throw
throw new Exception("You have some exception")
throw new IOException("Connection failed!!")
throws
public int myMethod() throws IOException, ArithmeticException, NullPointerException {}
You cannot declare multiple exceptions with throw. You can declare multiple exception e.g. public void method()throws IOException,SQLException.
checked exceptions can not be propagated with throw only because it is explicitly used to throw an particular exception. checked exception can be propagated with throws.
Exception propagation: An exception propagates from method to method, up the call stack, until it's caught. So if a() calls b(), which calls c(), which calls d(), and if d() throws an exception, the exception will propagate from d to c to b to a, unless one of these methods catches the exception.
what is exception propagation?
throw use for throwing actual Exception and throws declare at method it might throws Exception.
public int findMax(int[] array) throws Exception{
if(array==null)
throw new NullPointerException(...);
...
}
public void someMethod(List<Foo> someList) throws SomeException {
if (someList.isEmpty()) throw new SomeException();
}