In Java, if we create custom exception by extending Exception class then it will be considered as checked exception. By definition, checked exception are forced by the compiler like if we are writing below code then we are bound to catch FileNotFoundException
try{
fis = new FileInputStream("abc.txt");
}
catch(FileNotFoundException e)
{
System.out.println("The source file does not exist. " + e);
}
In order to invoke custom exception, I need to explicitly throw it. So how this is checked then? It should be unchecked as compiler is not forcing me anything.
Regards
Shaikh
The checked/unchecked refers to the requirement of handling the exception by the code that uses your method throwing exception.
Say You throw an unchecked exception in your method (RuntimeException or its subclass). You do not have to signal that your method throws it and anyone that uses your code does not need to explicitly handle it.
However if You throw checked exception (Exception that isn't subclass of RuntimeException) then your method must explicitly say that it throws exception and anyone that uses your code must handle that exception - either by also declaring their method as method that throws an exception (rethrow) or by using a try-catch block, around invocation of your method that throws checked exception.
Related
New Java programmers frequently encounter errors phrased like this:
"error: unreported exception <XXX>; must be caught or declared to be thrown"
where XXX is the name of some exception class.
Please explain:
What the compilation error message is saying,
the Java concepts behind this error, and
how to fix it.
First things first. This a compilation error not a exception. You should see it at compile time.
If you see it in a runtime exception message, that's probably because you are running some code with compilation errors in it. Go back and fix the compilation errors. Then find and set the setting in your IDE that prevents it generating ".class" files for source code with compilation errors. (Save yourself future pain.)
The short answer to the question is:
The error message is saying that the statement with this error is throwing (or propagating) a checked exception, and the exception (the XXX) is not being dealt with properly.
The solution is to deal with the exception by either:
catching and handling it with a try ... catch statement, or
declaring that the enclosing method or constructor throws it1.
1 - There are some edge-cases where you can't do that. Read the rest of the answer!
Checked versus unchecked exceptions
In Java, exceptions are represented by classes that descend from the java.lang.Throwable class. Exceptions are divided into two categories:
Checked exceptions are Throwable, and Exception and its subclasses, apart from RuntimeException and its subclasses.
Unchecked exceptions are all other exceptions; i.e. Error and its subclasses, and RuntimeException and its subclasses.
(In the above, "subclasses" includes by direct and indirect subclasses.)
The distinction between checked and unchecked exceptions is that checked exceptions must be "dealt with" within the enclosing method or constructor that they occur, but unchecked exceptions need not be dealt with.
(Q: How do you know if an exception is checked or not? A: Find the javadoc for the exception's class, and look at its parent classes.)
How do you deal with a (checked) exception
From the Java language perspective, there are two ways to deal with an exception that will "satisfy" the compiler:
You can catch the exception in a try ... catch statement. For example:
public void doThings() {
try {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
} catch (IOException ex) {
// deal with it <<<=== HERE
}
}
In the above, we put the statement that throws the (checked) IOException in the body of the try. Then we wrote a catch clause to catch the exception. (We could catch a superclass of IOException ... but in this case that would be Exception and catching Exception is a bad idea.)
You can declare that the enclosing method or constructor throws the exception
public void doThings() throws IOException {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
}
In the above we have declared that doThings() throws IOException. That means that any code that calls the doThings() method has to deal with the exception. In short, we are passing the problem of dealing with the exception to the caller.
Which of these things is the correct thing to do?
It depends on the context. However, a general principle is that you should deal with exceptions at a level in the code where you are able to deal with them appropriately. And that in turn depends on what the exception handling code is going to do (at HERE). Can it recover? Can it abandon the current request? Should it halt the application?
Solving the problem
To recap. The compilation error means that:
your code has thrown a checked exception, or called some method or constructor that throws the checked exception, and
it has not dealt with the exception by catching it or by declaring it as required by the Java language.
Your solution process should be:
Understand what the exception means, and why it could be thrown.
Based on 1, decide on the correct way to deal with it.
Based on 2, make the relevant changes to your code.
Example: throwing and catching in the same method
Consider the following example from this Q&A
public class Main {
static void t() throws IllegalAccessException {
try {
throw new IllegalAccessException("demo");
} catch (IllegalAccessException e){
System.out.println(e);
}
}
public static void main(String[] args){
t();
System.out.println("hello");
}
}
If you have been following what we have said so far, you will realise that the t() will give the "unreported exception" compilation error. In this case, the mistake is that t has been declared as throws IllegalAccessException. In fact the exception does not propagate, because it has been caught within the method that threw it.
The fix in this example will be to remove the throws IllegalAccessException.
The mini-lesson here is that throws IllegalAccessException is the method saying that the caller should expect the exception to propagate. It doesn't actually mean that it will propagate. And the flip-side is that if you don't expect the exception to propagate (e.g. because it wasn't thrown, or because it was caught and not rethrown) then the method's signature shouldn't say it is thrown!
Bad practice with exceptions
There are a couple of things that you should avoid doing:
Don't catch Exception (or Throwable) as a short cut for catching a list of exceptions. If you do that, you are liable catch things that you don't expect (like an unchecked NullPointerException) and then attempt to recover when you shouldn't.
Don't declare a method as throws Exception. That forces the called to deal with (potentially) any checked exception ... which is a nightmare.
Don't squash exceptions. For example
try {
...
} catch (NullPointerException ex) {
// It never happens ... ignoring this
}
If you squash exceptions, you are liable to make the runtime errors that triggered them much harder to diagnose. You are destroying the evidence.
Note: just believing that the exception never happens (per the comment) doesn't necessarily make it a fact.
Edge case: static initializers
There some situations where dealing with checked exceptions is a problem. One particular case is checked exceptions in static initializers. For example:
private static final FileInputStream input = new FileInputStream("foo.txt");
The FileInputStream is declared as throws FileNotFoundException ... which is a checked exception. But since the above is a field declaration, the syntax of the Java language, won't let us put the declaration inside a try ... catch. And there is no appropriate (enclosing) method or constructor ... because this code is run when the class is initialized.
One solution is to use a static block; for example:
private static final FileInputStream input;
static {
FileInputStream temp = null;
try {
temp = new FileInputStream("foo.txt");
} catch (FileNotFoundException ex) {
// log the error rather than squashing it
}
input = temp; // Note that we need a single point of assignment to 'input'
}
(There are better ways to handle the above scenario in practical code, but that's not the point of this example.)
Edge case: static blocks
As noted above, you can catch exceptions in static blocks. But what we didn't mention is that you must catch checked exceptions within the block. There is no enclosing context for a static block where checked exceptions could be caught.
Edge case: lambdas
A lambda expression (typically) should not throw an unchecked exception. This is not a restriction on lambdas per se. Rather it is a consequence of the function interface that is used for the argument where you are supplying the argument. Unless the function declares a checked exception, the lambda cannot throw one. For example:
List<Path> paths = ...
try {
paths.forEach(p -> Files.delete(p));
} catch (IOException ex) {
// log it ...
}
Even though we appear to have caught IOException, the compiler will complain that:
there is an uncaught exception in the lambda, AND
the catch is catching an exception that is never thrown!
In fact, the exception needs to be caught in the lambda itself:
List<Path> paths = ...
paths.forEach(p -> {
try {
Files.delete(p);
} catch (IOException ex) {
// log it ...
}
}
);
(The astute reader will notice that the two versions behave differently in the case that a delete throws an exception ...)
More Information
The Oracle Java Tutorial:
The catch or specify requirement
... also covers checked vs unchecked exceptions.
Catching and handling exceptions
Specifying the exceptions thrown by a method
when I try to catch this exception it gives me a compilation error message that says, "exception LinkedListException is never thrown in body of corresponding try statement". What does this mean?
try {
LList.Node someNode = list.nextNode(node);
// We should not get here.
assertTrue(false);
}
catch ( LinkedListException ex) {
// If we get here we are happy as it throw the exception
}
The exception must be thrown somewhere in your code using throw keyword.
For example,
The ArithmeticException is thrown some where deep inside the code . If you don't want to handle( just like how the person thought about writing ArithmeticException) you can bubble up like
void someMethod () throws Exception
{
throw new Exception();
}
The person who called this method have to handle it with try,catch , finally like we usually do for exceptions IOException etc.
So, if you want to throw your exception, add this throw new LinkedListException() some where in your try block where ever you want to raise an exception.
If the exception is not a RuntimeException, then it must be declared (in the method signature throws clause). As such, the compiler can check if the code you call might throw this exception or not, and will not let you add a catch they will never be exercised.
If you are sure that this exception can be thrown somewhere deep down in that code, then it must have been caught and ignored or wrapped in another exception on the way. Or you are compiling against the wrong version of the class.
import java.io.*;
class a {
public static void main(String [] args) {
try {
new a().go();
}
catch(Exception e) {
System.out.println("catch");
}
}
void go() {}
}
Already visited this link but didn't got my answer
If Exception class object is considered Checked : This code compiles fine even though Exception object will never be thrown from go method. EXACTLY the checked exceptions that can be thrown from the try block are handled and no other. So it cannot be checked.
If Exception class object is considered UnChecked : Exception class is not subclass of Error or RuntimeException so it cannot be unchecked.
Please help me to understand ... it is an object of which type.
Exception is a checked exception. It's more of an exclusion really; it's neither an Error nor a RuntimeException, which are both considered unchecked.
The unchecked exception classes are the run-time exception classes and the error classes.
The checked exception classes are all exception classes other than the unchecked exception classes. That is, the checked exception classes are all subclasses of Throwable other than RuntimeException and its subclasses and Error and its subclasses.
That said, your contrived example will still compile because Exception is the superclass to all runtime exceptions, which (for some reason) are expected to be caught in your code block. Since you don't declare Exception to be thrown on go, you are not required to catch it as it is not a checked exception.
Do not use code like this in production, as any checked exception or runtime exception will be caught by that block.
RuntimeException is a subclass of Exception, so your catch block picks up both checked and unchecked exceptions.
Check this link http://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html
The class Exception and any subclasses that are not also subclasses of RuntimeException are checked exceptions
So to answer your question, it is a checked exception.
If Exception class object is considered Checked
It is.
This code compiles fine even though Exception object will never be thrown from go method.
You can't know that. There could be a RuntimeException.
EXACTLY the checked exceptions that can be thrown from the try block are handled and no other.
That's not correct. The checked exceptions and the runtime exceptions are caught.
So it cannot be checked.
Invalid deduction from false premisses.
If Exception class object is considered UnChecked
It is checked. No need to consider the rest of this.
Exception class is not subclass of Error or RuntimeException so it cannot be unchecked.
Correct.
Exception class is considered Checked exception.
Checked exception means you need to enclose the method that throws Exception in Try catch
else you need to add throws declaration so that the parent method that called it would handle exeception.
Exception class itself is not a checked Exception..Checked Exceptions are exceptions that are child of Exception class e-g IOException etc
There are two things..
1- are you throwing it ??
2- are you talking about declaring it in catch clause.??
LETS DEMONSTRATE IT WITH EXAMPLE
1- if you are throwing any Exception class Except (RuntimeException or its child classes) then you have to handle it by catch clause or declare it by throws..no matter if it is Exception class or Throwable or other Checked Exceptions .e-g
void go() throws Exception
{
throw new Exception();
} //you have to handle or declare it
now calling method should have to handle or declare it
2- YOUR POINT IS HERE are you talking about declaring it in catch clause. (EXCEPTION VS OTHER CHECKED EXCEPTION)
Exception don't need to be thrown if declared in catch but checked Exception need to b thrown if catched..(simple answer is that)
void callingMethod()
{
try{ } // NO NEED TO THROW Exception OR Thowable
catch(Exception e){
e.printStakeTrace();
}
}
//IN CASE OF CHECKED EXCEPTIONS THAT ARE CHILD OF EXCEPTION YOU HAVE TO THROUGH IT IF YOU ARE CATCHING IT>>OTHERWISE COMPILER WILL TELL YOU TO THROUGH IT e-g
void callingMethod()
{
try{ } // here is compiler error..it says you have to through it
catch(IOException e){
e.printStakeTrace();
}
}
If the method is declared to throw the same exceptions thrown by some code and that code is also enclosed in a try/catch, will the exception be caught by the catch or will the error still be thrown? I am guessing that the catch has precedence although I am not 100% sure.
If I understand you correctly, you are asking:
void someMethod() throws SomeException {
try {
doSomethingElse()
} catch (SomeException e) {
// is this reached or does it throw from the method?
}
}
The catch clause will be triggered and the exception is considered handled. Unless you re-throw it from that block, it will not escape the method.
In my example, there is no need for your method to declare that it throws SomeException, because it doesn't.
Each catch block is an exception handler that handles the type of exception indicated by its argument. Once the exception is handled, it will not be thrown anymore unless you rethrow the exception in the catch block.
It is not a matter of one construct "taking precedence" over the other. They are saying different things.
(Borrowing #Duncan's example ...)
void someMethod() throws SomeException {
try {
doSomethingElse()
} catch (SomeException e) {
// is this reached or does it throw from the method?
}
}
Also, I will assume that SomeException is a checked exception.
This line here:
void someMethod() throws SomeException {
is saying that someMethod >>could<< throw SomeException. This is the contract: what the caller of the method needs to allow for.
It is not saying that it >>does<< throw the exception. What actually happens is determined by the behavior of the body of the method. In this example, the exception is being caught and handled, so we can say that even though the someMethod >>could<< throw the exception, in fact it >>does not<<.
OK ... but that is not the end of the story.
What if we changed the body of the method to not catch the exception? Now the ">>does not<<" becomes ">>could<<" ... depending on the signature for doSomethingElse() and its behavior.
What if we created a subclass that overrides someMethod with a different behavior. Now, the actual class of the target object will influence whether the exception can happen or not.
But through all of this, the meaning of throws SomeException in the method declaration remains the same. It tells the compiler that whenever this method is called, the caller must deal with the possibility of the checked exception ... even if there is no way that the code as currently written can propagate that exception.
To recap. Neither "takes precedence". They are saying different things.
I was playing around with some of my code and came across something I didn't fully understand. I have a class called SentimentClassifier, the constructor of which looks like this:
public SentimentClassifier(final int nGramToBeUsed) {
try {
classifier = (DynamicLMClassifier<?>) AbstractExternalizable.readObject(new File(etc));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have another class which creates this one, like so:
public TwitterManager(final int nGramToBeUsed) {
sentimentClassifier = new SentimentClassifier(nGramToBeUsed);
}
If I run the code like this, everything works fine. But if I change the first class from using try/catch to throw the exception, like so:
public SentimentClassifier(final int nGramToBeUsed) throws ClassNotFoundException, IOException {
classifier = (DynamicLMClassifier<?>) AbstractExternalizable.readObject(new File(etc));
}
Suddenly the second class complains that the IOException isn't being handled. Why is this thrown only for the thrown exception and not for the try/catch?
When you call a method M1 from another method M2:
If some code in M1 raises some Checked Exception, and the method M1 itself handles it, rather than throwing it, you don't have to worry about the exception while calling it.
Now, if the exception raised in M1, is not being handled in M1 itself, rather it is propagated up the stack trace, then M1 must declare that exception in the throws clause. This is just for the convenience of the calling method to know that it should be ready to handle those exception in case they are thrown. This is only the case with Checked Exception.
But if the calling method M2, doesn't handle that exception, it has the option to re-declare that exception to be thrown in it's own throws clause, in which case the exception will be propagated further up the stack trace.
If method M2 does neither of the previous two task, you will get a compiler error. Because you haven't given any proper path or way to handle the exception that can be thrown.
Note all the above arguments are true for Checked Exception only. For Unchecked exception, you don't need to handle it yourself, neither you need to declare it in throws clause.
Suggested Read:
Java: checked vs unchecked exception explanation
Unchecked Exception controversies
JLS - The Kinds and Causes of Exceptions
In Java, if a method declares that throws an Exception (other than RuntimeException), callers must handle the exception. They can do this one of two ways: catch it, or declare that they themselves throw it.
You moved the handling of these two exceptions from the SentimentClassifier constructor to its callers.
If the constructor declares any exceptions, the calling code must handle them or declare them. After all, the constructor could throw/propagate these exceptions, and any code that calls it must handle them.
When you catch an exception, it means that you will deal with it on the catch block, and its consequences, so the external code can continue to progress without being warned about the internal exception.
If your exception is thrown, you are forcing by contract to any creator/invoker class to deal with any declared exception that could be produced during the initialization/execution process, as it can be critical for the business logic.
In this case, if the exceptions that can be generated during init are critical, and could stop the class from working properly, they should be thrown, as the creator class TwitterManager could have a disfuncional or partially initialized instance of the SentinelClassifier object, leading to unexpected errors.