Throw checked exceptions - java

A few of my methods in Java throw exceptions such as NoSuchElementException, IllegalArgumentException, etc. But when using these methods, these exceptions appear to be unchecked. In other words, caller of my methods is not required to do a try/catch on my methods that throw those exceptions. I read around it seems that Exceptions by default are "checked" and only Errors are the ones "unchecked". But somehow, the exceptions I throw are also unchecked. It is weird.
How can I ensure that when my method throws an exception, the caller MUST catch the exception at compile time? Simply said, how can I throw a checked exception?
Thanks!

Only RuntimeException and its subclasses are unchecked. (Well, Error and its subclasses are as well, but you shouldn't be messing with Errors.) All you need to do to throw a checked exception is ensure that it doesn't extend RuntimeException.

See this hack, it might help (hope it's not OT).
public class Test {
// No throws clause here
public static void main(String[] args) {
doThrow(new SQLException());
}
static void doThrow(Exception e) {
Test.<RuntimeException> doThrow0(e);
}
#SuppressWarnings("unchecked")
static <E extends Exception> void doThrow0(Exception e) throws E {
throw (E) e;
}
}

Whether an exception is checked or not checked is NOT how you throw it or declare it, it is only dependent on whether the exception you choose is derived from RuntimeException or not. The ones you list above, all are derived from RuntimeException and so clients of your method do not need to catch them.

All sub-classes of Throwable are checked except sub-classes of Error and RuntimeException. (You can sub-class Throwable directly)
The compiler checks these Exception, however they have no special place at runtime. i.e. you can throw a checked Exception without the compiler knowing and it will behave normally.
e.g.
public static void throwChecked(Throwable t) /* no throws clause */ {
Thread.currentThread().stop(t);
}
public static void main(String... args) /* no throws clause */ {
throwChecked(new Throwable());
}
This compiles and prints the Throwable as you might expect.

I think you should take a step back and learn the theory behind why to throw a checked exception vs an unchecked exception. The Java tutorial on exceptions is a good resource.
From the page entitled Unchecked Exceptions — The Controversy:
Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way.

Exceptions that extends RuntimeException do not have to be declared.
You can declare the method: throws Exception or even throws Throwable and that will have to be handled (though it is not advised).

Related

Add auto-clear notification on Cordova FirebaseX plugin [duplicate]

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

Compile error: unreported exception Add; must be caught or declared to be thrown

I want to create user-defined exception with addition but I get a compilation error.
class Test{
public static void main(String[] args){
int a=9, b=67, result;
result = a+b;
throw new Add("Addition has been performed");
}
}
class Add extends Throwable{
Add(){
printStackTrace();
}
Add(String message){
System.out.println(message);
printStackTrace();
}
}
The error is:
Practice.java:8: error: unreported exception Add; must be caught or declared to be thrown
throw new Add("Addition has been performed");
I would point out that irrespective of the compilation error, and the possible fixes, it is a bad idea to extend Throwable.
It is unnecessary. You can / should extend Exception or RuntimeException or any of their subclasses.
There is a lot of code that assumes that all exceptions are Exception or Error or their subtypes, not some "random" subtype of Throwable.
The generic meaning of a random subclass of Throwable is unclear; e.g. see Which subclass of Throwable should be caught and which shouldn't?
See also the discussion in this Q&A:
Extending Throwable in Java
It is also a bad idea for an exception's constructors to be printing or logging error messages and stacktraces. It should be up to the code that catches the exception to decide what to do with them.
To make your exception unchecked declare it in the following way
class Add extends RuntimeException {
}
Either catch/rethrow the Add throwable
or extend it from RuntimeException - they are not mandatory to be caught.
class Add extends RuntimeException
If you do not want to make your exception unchecked you need either to declare that your method might throw this exception
public static void main(String[] args) throws Add {
or surround it with try/catch statements
try {
throw new Add("Addition has been performed");
} catch (Add add) {
add.printStackTrace();
}
Overall I would suggest you to use an IDE they are really good at helping you with these kind of problems.
You have Successfully created and throw the Exception but use Try and
Catch block to handle it.
First, in Java there are 2 types of exception. Checked and unchecked. Checked are exceptions thrown that you have to handle by either catching them ( surrounding the block, portion of code, containing methods that would throw an exception like yours) or declaring that the parent method calling this method throwing an exception.
Throwable is base class of all errors in Java. There are multiple types of errors, a sub type Is exceptions.
Important to not as well is that you seem to throw an exception on success which isn’t the best to do because exceptions are costly in terms of resources. Better use events in this case to broadcast that addition happened.

Is it okay to declare a checked exception for an exception thrown by a called method?

Consider this:
public void Do() throws Exception {
if (blah) throw new Exception(...);
Thingy thingy = ...;
Foo(thingy);
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Throwable { ... }
In this case, is it okay to not handle EmptyThingyException inside Do and declare Do like so:
public void Do() throws Exception, EmptyThingyException {
or do I have to handle EmptyThingyException inside Do and throw it back again like so:
public void Do() throws Exception, EmptyThingyException {
try {
} catch (EmptyThingyException empty) {
throw empty;
}
...
}
The short answer to the question is:
Yes, it's correct to declare a checked exception thrown by a called method.
How a method achieves its purpose is an implementation detail and it shouldn't matter to the interface how much it does directly or how much it delegates to methods. The language rules about checked exceptions are carefully defined to make sure methods advertise all checked exceptions they may throw or methods they call throw (but are not handled by the method itself). Letting an unhandled exception get 'thrown through' a method is how things are supposed to work.
Indeed the answer is in the name of the construct "non-local exception handling" it was conceived to take effort out of endless error handling all the way up a call chain when the only real action is "that didn't work" at some point near the start.
To align to that method, you should only catch exceptions you're going to do something about.
Clean up code should be achieved with finally so the normal reasons to catch an exception are to log it and/or abandon a task at some point rather than letting the stack unwind further.
In this specific case the best answer would be to throw an IllegalArgumentException:
throw new IllegalArgumentException("thingy==null || thingy.isEmpty()");
That's unchecked and wisely so. Correct code shouldn't encounter illegal arguments and they should expect to be thrown rarely and be indicative of program flaw (either in the class, it's package or consumer code). External and user input should be validated directly and programs shouldn't rely on IllegalArgumentException.
In practice IllegalArgumentException and IllegalStateException should cover 'internal errors' meaning "You can't do this with that" or "You can't do that right now" respectively and should be commented to specify the fault.
The idea that you might sub-class those two because consumer code might respond differently to different illegal actions it might take is bodging pure and simple.
Program correctness includes that a program never makes an illegal call on some other part of the program or enters an invalid or corrupted state and exceptions only occur as a result of environmental failures that mean a program or sub-task in a program cannot be completed as intended.
if you want to do something after exception happen, then use try-catch, or you can just declare it on the method.
Beyond that, if EmptyThingyException is sub class of Exception, then it is no need to declare EmptyThingyException when you have declared Exception.
1- Declare the specific checked exceptions that your method can throw
public void foo() throws Exception { //Incorrect way
}
Always avoid doing this as in above code sample. It simply defeats the whole purpose of having checked exception. Declare the specific checked exceptions that your method can throw. If there are just too many such checked exceptions, you should probably wrap them in your own exception and add information to in exception message. You can also consider code refactoring also if possible.
2- Always catch only those exceptions that you can actually handle
catch (NoSuchMethodException e) {
throw e; //Avoid this as it doesn't help anything
}
Well this is most important concept. Don’t catch any exception just for the sake of catching it. Catch any exception only if you want to handle it or, you want to provide additional contextual information in that exception. If you can’t handle it in catch block, then best advice is just don’t catch it only to re-throw it.
3- Avoid using Throwable class
Throwable is the superclass of Exception and Error, as far as I know you need to use Throwable when you want to deal with both exceptions and errors, but it's definitely not your concern here, most of the java code deal with Exception and it's the way to go whenever you need to deal with checked exceptions http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html.
**
Well if I was you I would do something like :
public void Do() throws BlahIsFoundException{
try {
if (blah) throw new BlahIsFoundException(...);
Thingy thingy = ...;
Foo(thingy);
} catch(EmptyThingyException exception) {
//Handle the exception correctly, at least log it
} finally {
//Do some clean up if needed, for example close a database connection or free some resources.
}
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Exception { ... }
public class BlahIsFoundException extends Exception { ... }
Hope that helps, here are some good documents to read :
http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
http://howtodoinjava.com/best-practices/java-exception-handling-best-practices

Exception Handling in JAVA and Use of throws statement

Why is it so? This code compiles fine but throw an exception at run time
public class Except
{
public static void main(String args[])
{
System.out.println("Hey, I am under main");
method();
}
static void method()
{
throw new NullPointerException();
}
}
But this code isn't compiling
public class Expect
{
public static void main(String args[])
{
System.out.println("Hey, I am under main");
method();
}
static void method()
{
throw new IllegalAccessException();
}
}
Why this is so?That changing the type of exception,the second code is not compiling.Can somebody please explain,and I have used the throw statement in first code,and since its compiling fine,then what is the use of writing throws statement with method declaration.
I am using jdk 1.8.0_45
NullPointerException is a sub-class of RuntimeException, which makes it an unchecked exception, which doesn't have to be handled or declared in a throws clause.
IllegalAccessException is a checked exception, so it must either be caught or be declared in the throws clause of any method that may throw it.
The second snippet will compile if you add a throws clause :
static void method() throws IllegalAccessException
{
throw new IllegalAccessException();
}
Checked exceptions must be explicitly caught or propagated as described in try-catch Exception Handling. Unchecked exceptions do not have to be caught or declared thrown.
Checked exceptions in Java extend the java.lang.Exception class. Unchecked exceptions extend the java.lang.RuntimeException.
Unchecked Exceptions List:
ArrayIndexOutOfBoundsException
ClassCastException
IllegalArgumentException
IllegalStateException
NullPointerException
NumberFormatException
AssertionError
ExceptionInInitializerError
StackOverflowError
NoClassDefFoundError
Checked Exceptions List:
Exception
IOException
FileNotFoundException
ParseException
ClassNotFoundException
CloneNotSupportedException
InstantiationException
InterruptedException
NoSuchMethodException
NoSuchFieldException
I want to add my two cents on the difference between checked and unchecked exceptions, from user's point of view.
Imagine a simple application, where user registers to a system providing name, lastname and a phone number.
Let's take a look at checked exceptions first. If user enters 12312312 for the name field, app should throw a checked exception.Similarly if user enters angelo as phone number, app again should throw a checked exception. Because neither 12312312 is a valid name for a person, nor is angelo as a phone number. We use checked exceptions in such cases. Because it is basically a user error and with proper feedback, user can correct this kind of errors.
On the other hand, unchecked exceptions were not user exceptions. For this kind of situations, there is simply NOTHING that user could do. For instance, connection to the database may get lost. Or When developer created the database field for above example, he might defined the name field in the database as a boolean field. (I am exaggerating here a bit).
I hope this helps too.

Throw IOException instead of Exception

I have method1() which is called from lots of other methods throughout the code. This is the signature of the method:
public void method1(final Properties properties) throws IOException {}
All methods calling this method also throw IOException.
The actual code in method1() changed, so now instead of IOException it throws some other exceptions that extend Exception and not IOException anymore.
I don’t want to change the signature of all methods calling method1().
Is it ok to create IOException and still throw IOException from method1() and hence the methods calling method1()?
Something like below:
Try {
// code
} catch (Exception e) {
throw new IOException(e.getCause());
}
No, you should not do this, because you will confuse every other developer reading your code or reading stacktraces.
From the software-design point of view, the error happened a lot earlier.
If your code is like an API and used by others, you may better have used Custom-Exceptions and wrapped the IOException as root-cause.
If you have the complete source, you should refactor the source and add another exception signature.
You need to save the original exception as the cause, so you're not losing the original message or stacktrace. Calling e.getCause() in your code example is skipping over the exception that you caught and getting its cause, which is suspicious-looking.
Also it would be better to specify the particular exceptions that the method catches, rather than using a catch-all Exception type. Catching Exception would result in things like NullPointerExceptions getting caught that were not trapped before.
The best thing to do here is change the exceptions thrown by your method to a custom type that doesn't let the implementation details bleed through to the callers. Your method signature should change to
public void method1(final Properties properties) throws SomeCustomException {
try {
.... // do whatever
} catch (AException | BException | CException e) {
throw new SomeCustomException(e);
}
}
This will work technically.
However, catching Exception or Throwable is almost everytime a bad idea (as is throwing them), because you will also catch all other Exceptions, besides RuntimeExceptions.
If you can change the code of all calling classes (i.e. you are not developing a framework/library), you should do so. Because I assume you meant method1() throws a more specific type now.
You may also think about throwing a Subtype of RuntimeException which does not need to be catched, and is a good idea for errors that can't be corrected (e.g. a bad configuration).
(see Clean Code by Robert Martin)

Categories

Resources