Reputation: 4921
In one of my interview, they asked me, is it possible to write Throwable in catch() like this
try{
some code
}
catch(Throwable t)
{
}
I said yes. it will not give a compile time error but jvm would not handle it if there occur an Error
(sub class of Throwable ), since Errors are irreversible conditions that can not be handled by jvm. than they further asked than what is the use of writing Throwable .
Please give me proper reply can we use Throwable in catch. if yes why.
Upvotes: 11
Views: 18429
Reputation: 74551
Throwable
but as best practice, it is not advised to catch Throwable
. Throwable
includes Errors
too, we should not catch errors, it helps to identify JVM issues.Upvotes: 2
Reputation: 718698
Yes it is possible to catch Throwable
.
Whether the JVM / application will be able to continue if you catch an error depends on the actual error that occurred, what caused it, and what (if anything) your application does next.
In some cases, the JVM may be in such a bad way that no recovery is possible.
In some cases, the JVM is fine ... as long as you don't do certain things. Class loading errors are a good example. If your application doesn't attempt to use the class or dependent classes that you failed to load, you should be fine to continue. (In reality, applications are not designed to continue without classes that fail to load ... but if it was, it could.)
In some cases, the core JVM will be fine, but unspecified damage could have been done to the application's data structures, and/or to its threads and computation state. OOMEs are liable to do this to you, especially if your application is not designed to deal with threads that die unexpectedly.
Catching and recovering from OOMEs is problematic for another reason. While the termination of the current computation will free up some heap space, there's a good chance that it won't free up enough space. So you can easily get into a situation where your application is repeatedly throwing and catching lots of OOMEs, and making no real progress.
All of this means that it is generally a bad idea to try to recover from errors. And that's in line with what the javadoc for error says:
"An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."
Upvotes: 3
Reputation: 12538
It is possible to catch Throwable
. And yes, you will also catch instances of java.lang.Error
which is a problem when it comes to e.g. OutOfMemoryError
's. In general I'd not catch Throwable
's. If you have to, you should do it at the highest place of your call stack, e.g. the main
method (you may want to catch it, log it, and rethrow it).
I agree with your argumentation, it does not make sense to catch events you're not able to handle (e.g. OutOfMemoryError). A nice post is here.
Upvotes: 13
Reputation: 14045
Catching Throwable will catch all Exceptions (including RuntimeExceptions) and all Errors. It is not recommended to catch any of the parent Throwables (Throwable, Error, Exception or RuntimeException) but it is not uncommon to find this if a method throws too many checked exceptions or throws Exception.
It is not uncommon in certain APIs to document a method as throws Exception. This provides some flexibility at the expense of control. I like to define a new Exception class to handle this sort of case but that is personal preference.
The following simple class shows samples of the throwable types and corresponding catch blocks.
public class ThrowableExamples {
public static void main(String[] args) {
try {
// throw new NoSuchMethodException("Exception");
// throw new Exception("Exception");
// throw new IllegalStateException("RuntimeException");
// throw new RuntimeException("RuntimeException");
throw new NoSuchMethodError("Error");
// throw new Error("Error");
// throw new Throwable("Throwable");
} catch (RuntimeException e) {
System.out.println("Caught RuntimeException: " + (e.getMessage().equals("RuntimeException") ? "Expected" : "Unexpected"));
} catch (Exception e) {
System.out.println("Caught Exception: " + (e.getMessage().equals("Exception") ? "Expected" : "Unexpected"));
} catch (Error e) {
System.out.println("Caught Error: " + (e.getMessage().equals("Error") ? "Expected" : "Unexpected"));
} catch (Throwable e) {
System.out.println("Caught Throwable: " + (e.getMessage().equals("Throwable") ? "Expected" : "Unexpected"));
}
}
}
Upvotes: 0
Reputation: 613
Throwable can be used instead of any individual exception/error. However it is recommended to pass through ThreadDeadException. So you can add extra catch clause for it, or filter by type.
Upvotes: 1