I'm trying to come up with some simple rules to remember regarding exceptions in overridden methods in Java 8.
I've seen some posts explaining this in a kind of long way or not so clear to me.
Assume when saying "Checked exception" it means the method has throws <checked-exception> in its signature etc.
Checked exceptions can stay the same or be narrowed, even to not throwing at all.
Unchecked exceptions (runtime exceptions) have no rules (can be narrowed or widened or neither).
To keep the statement simple assume that narrowing "not throwing at all" is "not throwing at all" and widening "not throwing at all" is to throw any exception (corresponding to checked/unchecked case)
Summarizing this to:
checked >= overriding-checked
unchecked, overriding-unchecked are independent
Is this all (and correct?) or are there some cases missing?
You're correct.
Let's say we have classes
public class Parent {
public void doit() throws IOException {
throw new IOException();
}
}
public class Child extends Parent {
public void doit() throws FileNotFoundException {
throw new FileNotFoundException();
}
}
Checked exceptions are the ones that you're required to handle. If Child were to throw a checked exception that is not an IOException (FileNotFoundException is an IOException, so it's okay as written), that would mean that this code lets this checked exception roam free:
Parent object = new Child();
try {
object.doit();
} catch (IOException ex) {
// thoughtful and careful handling
}
This would create a situation when a method threw a checked exception that is not declared in its throws list and defeat the definition and purpose of checked exceptions. Therefore language designers prohibited this.
Related
Are these code statements equivalent?
Is there any difference between them?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Yes, there's a huge difference - the latter swallows the exception (showing it, admittedly), whereas the first one will let it propagate. (I'm assuming that showException doesn't rethrow it.)
So if you call the first method and "do something" fails, then the caller will have to handle the exception. If you call the second method and "do something" fails, then the caller won't see an exception at all... which is generally a bad thing, unless showException has genuinely handled the exception, fixed whatever was wrong, and generally made sure that calculateArea has achieved its purpose.
You'll be able to tell this, because you can't call the first method without either catching Exception yourself or declaring that your method might throw it too.
They differ in where the responsibility to deal with the Exception lies. First one just throws Exception, so it does not handle it. The code that calls the method needs to handle the Exception. Second one catches and handles the Exception within the method, so in this case the caller doesn't have to do any exception handling, provided showException() itself does not throw another exception.
Yes. The version which declares throws Exception will require the calling code to handle the exception, while the version which explicitly handles it will not.
i.e., simply:
performCalculation();
vs. moving the burden of handling the exception to the caller:
try {
performCalculation();
catch (Exception e) {
// handle exception
}
Yes, there is a great deal of difference between them. The in the first code block, you pass the exception to the calling code. In the second code block you handle it yourself. Which method is correct depends entirely on what you are doing. In some instances, you want your code to handle the exception (if a file isn't found and you want to create it, for instance) but in others, you want the calling code to handle the exception (a file isn't found and they need to specify a new one or create it).
Generally speaking as well, you don't want to catch a generic exception. Instead, you'll want to catch only specific ones, such as FileNotFoundException or IOException because they can mean different things.
There is one particular scenario where we cannot use throws, we have got to use try-catch.
There is a rule "An overridden method cannot throw any extra exception other than what its parent class is throwing". If there is any extra exception that should be handled using try-catch.
Consider this code snippet.
There is a simple base class
package trycatchvsthrows;
public class Base {
public void show()
{
System.out.println("hello from base");
}
}
and it's derived class:
package trycatchvsthrows;
public class Derived extends Base {
#Override
public void show() {
// TODO Auto-generated method stub
super.show();
Thread thread= new Thread();
thread.start();
try {
thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// thread.sleep(10);
// here we can not use public void show() throws InterruptedException
// not allowed
}
}
When we have to call thread.sleep() we are forced to use try-catch, here we can not use:
public void show() throws InterruptedException
because overridden method can not throw extra exceptions.
If you threw an exception, the child method (which overrides this) should handle the exception
example:
class A{
public void myMethod() throws Exception{
//do something
}
}
A a=new A();
try{
a.myMethod();
}catch Exception(e){
//handle the exception
}
I assume that by "identical" you are referring to behavior.
A behavior of a function can be determined by:
1) Returned value
2) Thrown exceptions
3) Side effects (i.e changes in the heap, file system etc)
In this case, the first method propagates any exception, while the second throws no checked exception, and swallows most of the unchecked exceptions as well, so the behavior IS different.
However, if you guarantee that "do something" never throws an exception, then the behavior would be identical (though the compiler will require the caller to handle the exception, in the first version)
--edit--
From the point of view of API design, the methods are completely different in their contract. Also, throwing class Exception is not recommended. Try throwing something more specific to allow the caller to handle the exception better.
Many times you want the caller to handle the exception. Let's say you have the caller call a method which calls another method which calls another method, instead of having each method handle the exception, you can just handle it at the caller. Unless, you want to do something in one of the methods when that method fails.
The caller of this method will need to either catch this exception or declare it to be rethrown in it's method signature.
private void calculateArea() throws Exception {
// Do something
}
In the try-catch block example below. The caller of this method doesn't have to worry about handling the exception as it has already been taken care of.
private void calculateArea() {
try {
// Do something
} catch (Exception e) {
showException(e);
}
}
private void calculateArea() throws Exception {
....do something
}
This throws the exception,so the caller is responsible for handling that exception but if caller does not handle the exception then may be it will given to jvm which may result in abnormal termination of programe.
Whereas in second case:
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Here the exception is handled by the callee,so there is no chance of abnormal termination of the program.
Try-catch is the recommended approach.
IMO,
Throws keyword mostly used with Checked exceptions to convince
compiler but it does not guarantees normal termination of program.
Throws keyword delegate the responsibility of exception handling to
the caller(JVM or another method).
Throws keyword is required for checked exceptions only ,for unchecked
exceptions there is no use of throws keyword.
I'm developing a custom Exception class, in which I have the following constructors:
public class UserException extends Exception
{
string message;
public UserException() {
super();
}
public UserException(String message, Throwable cause)
{
super(message, cause);
this.cause = cause;
this.message = message;
}
}
And I create a new custom exception like this:
private Camera.PreviewCallback SetPreviewCallBack() throws UserException {
.......
// Something went wrong
throw new UserException("Something failed.", new Throwable(String.valueOf(UserExceptionType.CaptureFailed)));
}
But when I insert my throw new UserException(...) it tells me to surround it with try/catch!! That's not the idea, isn't it? I want to throw custom exceptions when I need them to be thrown, without surronding my new Exceptions with more try/catch clauses.
So, what I'm doing wrong? What I'm misunderstanding?
In addition to Eran's answer, you could also make your custom Exception extend RuntimeException, which does not need to be caught.
If the method that throws this exception doesn't handle it (i.e. it doesn't catch it), it must declare it in the throws clause, since this is a checked exception.
public void yourMethod () throws UserException
{
...
throw new UserException("Something failed.", new Throwable(String.valueOf(UserExceptionType.CaptureFailed)));
...
}
if your Custom Exception extends from Exception class, it must be handled (using try-catch) or passed on to caller (using throws). If you just want to leave it to runtime to handle the exception, You need to extend it from RuntimeException Class
Since its the 1st case in your scenario, You should do something like this:
public void surroundingMethod() throws UserException{
throw new UserException("Something failed.", new Throwable(String.valueOf(UserExceptionType.CaptureFailed)));
}
this will essentially pass your exception to the caller, so now it will be caller's responsibility to handle it with try-catch or pass it on again.
so again, u need to modify calling instruction as
public void callingMethod () {
try {
surroundingMethod();
} catch (UserException ex){
}
}
You should either declare your methods as throws UserException - or make your exception extend RuntimeException.
The later is officially unadvised, but is often used to bypass the java's declared exception mechanism.
In Java, when you throw a checked Exception, there is one more thing you are required to do:
1. Either add a try-catch block around the throw and handle this Exception within the same method.
2. Or add a throws statement to the method definition, transferring the responsibility for the handling of the the Exception to a higher-level method.
This is part of the overall OOP paradigms of modularity & abstraction: who is responsible for handling an Exception, the caller of a method or the method itself ? The answer depends on the nature of the Exception.
Reading about Exceptions in this book, I found this statement:
Checked exceptions are checked by the compiler at compile time.
and
The compiler does not check unchecked exceptions at compile time.
So, if also we can say that IOException or SQLException are below the Checked Exceptions class tree. How would java compiler know there will be an exception and no for IllegalArgumentException which might remain inside the code as my understanding.
Also, what does exactly the fact of being obligatory to get the Checked exceptions caught and not for Unchecked mean?
A checked exception requires that you add a throws declaration to the method signature, or you add a try catch block around it.
public void checked() throws IOException {
throw new IOException(); // compiles just fine
}
public void checked() {
try {
throw new IOException();
} catch (IOException e) {
// ...
}
}
This will not work:
public void checkedWithoutThrows() {
throw new IOException(); // will not compile
}
An unchecked exception does not need this.
public void unchecked() {
throw new RuntimeException();
}
And, just for completeness, the way to determine unchecked from checked exceptions is that unchecked exceptions all descend from RuntimeException at some point or another.
exceptions in java all work the same way.
the difference between checked and unchecked exceptions (which are all subclasses of RuntimeException) if that for a method that throws a checked exception whoever calls that method has to either try/catch the exception, or declare his own method as throwing that exception.
so if i have a method:
void throwsACheckedException() throws SomeCheckedException;
whoever calls it must do one of 2 things. either:
try {
throwsACheckedException();
} catch (SomeCheckedException e) {
//do something
}
or
void someCallingMethod() throws SomeCheckedException { //pass it on
throwsACheckedException();
}
unchecked exceptions you dont have to declare, and whoever calls the method does not have to explicitly catch. for example:
void someInnocentLookingMethod() {
throw new NullPointerException("surprise!"); //...extends RuntimeException
}
and then you can simply invoke it, without the try/catch hassle:
void unsuspectingVictim() {
someInnocentLookingMethod();
}
unchecked exceptions are usually used for things that can creep up on you at any point and so forcing developers to try/catch them would make the code very tedious (NullPointerException, for example), although there are those who thing checked exceptions are evil entirely :-)
For Checked exceptions, you see error at compile time and says that you have to handle them.
Run time exceptions do not give any error or warning to handle in your code.
Compiler expects exceptions (Checked exceptions) and asks you to handle it.
I am new to Android mobile application development.
I would like to know, how can I handle exceptions like HttpConnection related exceptions or any other exceptions? Do I need to display an AlertDialog to the user?
Kindly provide a sample code or project source code on how can I handle HttpConnection or similar type of Exceptions.
There are 2 different kinds of exceptions in Java: Checked and Unchecked. There is a big debate over which one is better to use, both arguments are good.
Basically a Checked exception is derived from java.lang.Exception and it requires that if you don't specify your method as "throws MyCheckedException" then you must catch and handle the exception within your method.
// throw the exception
void foo() throws MyCheckedException
{
throw new MyCheckedException();
}
// or handle the exception
void foo()
{
try {
throw new MyCheckedException();
} catch (MyRuntimeException e) {
e.printStackTrace();
}
}
An Unchecked exception, derived from java.lang.RuntimeException, requires neither that you specify "throws" in your method definition nor that you handle it.
void foo()
{
throw new MyUncheckedException();
}
The advantage of Checked is that the compiler will warn you when you haven't handled an exception.
The disadvantage is that you have to declare either a try/catch block or a throws for every Checked exception, and the upper level code can get pretty cumbersome, trying to handle all the different types of Exceptions.
For this reason, if you're careful you might prefer using Unchecked Exceptions.
BTW, you can only choose your exception type when you define your own.
When encountering Exceptions from Java or a 3rd party library, you have to decide how to handle it. e.g. If a 3rd party method throws CheckedException1, then you have to either handle it, or declare the calling method as "throws CheckedException1". If you want to avoid using Checked Exceptions then you can wrap it in an Unchecked Exception and throw that.
void foo() // no throws declaration
{
try {
thirdPartyObj.thirdPartyMethod(); // this throws CheckedException1
}
catch (CheckedException1 e) {
throw new MyUncheckedException(e); // this will wrap the checked in an unchecked.
}
}
Note that you can throw the Unchecked exception without the "throws" declaration. To access the original CheckedException1 from higher up, you can use the .getCause() method of your Unchecked exception.
void caller()
{
try {
foo();
} catch (MyUncheckedException e) {
CheckedException1 ce1 = e.getCause();
ce1.printStackTrace();
}
}
... but because the exception from foo() is Unchecked, you don't have to handle it or declare "throws".
Regarding logging, there are different schools of thought on this.
Log it when the exception occurs (low - level)
Log it when it reaches the top (high - level)
Log it when you have enough information to make an appropriate action and/or a log message. (mid - level)
A good policy I've found is to install an uncaught exception handler which will take care of all uncaught (obviously unchecked) exceptions. This way anything that is missed will be logged and potentially handled before crashing the system.
public class MyExceptionHandler implements UncaughtExceptionHandler
{
#Override
public void uncaughtException(Thread thread, Throwable ex)
{
ex.printStackTrace();
}
}
// In your high-level code
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
and all for Exceptions that can be handled gracefully, catch and handle them in a module where you know enough about the situation to possibly correct the problem and try again.
How you handle exception depends on the exception. If the exception is something that you cannot recover from, and the user needs to know about then you could catch the exception and show it in an AlertDialog:
try {
// do something
} catch (SomeImportantException e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("User friendly text explaining what went wrong.");
AlertDialog alert = builder.create();
alert.show();
}
For more info on the dialog, see creating dialogs.
Alternatively, if the exception is something that you can deal with, you can just log information about the exception and move on.
try {
// do something
} catch (SomeLessImportantException e) {
Log.d(tag, "Failed to do something: " + e.getMessage());
}
You could use the ACRA plugin that offers this functionality or BugSense to gather error reports.
Disclaimer: I am a founder at BugSense.
I want a method that can throw any Throwable including sub classes of Exception. Ive got something that takes an exception, stashes it in a thread local, then invokes a class.newInstance. That class ctor declares that it throws Exception then takes the threadlocal and throws it. Problem is it does not work for the two declared Exceptions thrown by Class.newInstance() namely IllegalAccessException and InstantiationException.
Im guessing any other method using some sun.* class is just a hack and not really reliable.
Wrapping is not an option because that means catchers are catching a diff type and that's just too simple and boring...
static public void impossibleThrow(final Throwable throwable) {
Null.not(throwable, "throwable");
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
try {
THROW.set((Exception) throwable);
THROWER.newInstance();
} catch (final InstantiationException screwed) {
throw new Error(screwed);
} catch (final IllegalAccessException screwed) {
throw new Error(screwed);
} finally {
THROW.remove();
}
}
private final static Class<Impossible> THROWER = Impossible.class;
private final static ThreadLocal<Exception> THROW = new ThreadLocal<Exception>();
static private class Impossible {
#SuppressWarnings("unused")
public Impossible() throws Exception {
throw THROW.get();
}
}
From Java Puzzlers (puzzle 43):
public static void impossibleThrow(Throwable t)
{
Thread.currentThread().stop(t); // Deprecated method.
}
The book shows other methods of achieving the same problem, one is a simplified version of yours, the other exploits generic type erasure to throw any Throwable where an Error is expected.
If you want an Exception to bubble up through code not expecting that exception then just wrap it in a RuntimeException
} catch (RuntimeException e) {
throw e; // only wrap if needed
} catch (Exception e) {
throw new RuntimeException("FOO went wrong", e);
}
Remember to let the message be informative. Some day you will have to fix a bug based only on the information in the stack trace.
Wrapping an exception inside a RuntimeException (as suggested by Thorbjørn) is the way to go. However, you usually want to maintain the stacktrace of the original excpetion. Here's how:
public static void rethrow(final Throwable t)
{
if(t instanceof RuntimeException)
throw (RuntimeException) t;
RuntimeException e = new RuntimeException(t);
e.setStackTrace(t.getStackTrace());
throw e;
}
I patched javac to remove the error, compiled impossibleThrow(), renamed the source file to something that does not end in .java (which forces the next compile to use the existing .class) and used that.
There is some validity for this question as a debugging tool. Suppose you are working with some code that may have failed and you see that it (perhaps) catches certain exceptions and (perhaps) throws certain exceptions. You suspect that an unexpected exception was not caught. However, the underlying code/system is too complex and the bug is too intermittent to allow you to step through in the debugger. It can be usefull to add the throwing of an exception without changing the method in any other way. In this case, wrapping the exception with a RuntimeException would not work, because you want the calling methods to behave normally.