Throwing An Exception In Java - Javamex
Maybe your like
Throwing an exception in Java
Exceptions are used to control error flow in a Java program. Exceptions work as follows:
- At any point where an error condition is detected, you may throw an exception using the Java throw keyword.
- When an exception is thrown, normal program flow stops and control is passed back to the nearest suitable surrounding catch block.
- If an exception is thrown back from a method, then that method does not return a value as normal.
- If there is no catch block that can catch the method, then it will eventually be passed to an uncaught exception handler.
- Exceptions can be checked or unchecked, depending on their class.
- A method must declare which checked exceptions (if any) it throws, but does not have to declare unchecked exceptions.
- There are various standard unechecked exceptions that you can use for common conditions (and which will be thrown by the JVM and platform API methods), including IllegalArgumentException and NullPointerException.
- There are also various exceptions and errors thrown by the JVM itself when executing code, allocating memory, decoding class files etc.
How to throw an exception
To throw an exception, we generally use the throw keyword followed by a newly constructed exception object (exceptions are themselves objects in Java). Most exception constructors will take a String parameter indicating a diagnostic message. For example, we can check an input parameter to our method and throw an IllegalArgumentException if it is invalid:
public void calculate(int n) { if (n > MAX_VALUE) { throw new IllegalArgumentException("Value too big (" + n + ")"); } ... }In complex programs, it is generally good practice to sanity-check arguments and throw exceptions such as IllegalArgumentException or NullPointerException so that the source of the issue is obvious.
How to throw a checked exception
We can simply throw an IllegalArgumentException or NullPointerException because if you look at their definitions, you will see that they extend RuntimeException. RuntimeException and its subclasses are so-called unchecked exceptions: they can be thrown at any time, without the method that throws them having to explicitly declare that it may throw them, or without the surrounding code having to explicitly catch them.
But what about "ordinary" checked exceptions— subclasses of Exception but not RuntimeException (see the exception hierarchy). A common example is IOException. If you throw one of these checked exceptions, you must either:
- catch it within the method ;
- decalre that the method throws it.
In the following example, we have a method deleteFiles(), which in turn calls Files.delete(). The Files.delete() method declares that it throws an IOException. Therefore, because we call this method, we must ourselves declare that our method throws this exception:
public void deleteFiles(Path[] files) throws IOException { for (Path f : files) { Files.delete(f); } }If we try to throw a checked exception such as IOException (or call a method that can throw it) without declaring that our method can throw it, then we will get a compiler error.
Alternatively, we may decide that there is no need to interrupt the process and have the caller deal with a failure to delete a single file. Instead, we can catch the exception within our method:
public void deleteFiles(Path[] files) { for (Path f : files) { try { Files.delete(f); } catch (IOException ioex) { System.err.println("Warning: failed to delete " + f); } } }Rethrowing an exception
Sometimes, we may want to do both things: catch the exception and then re-throw it to the caller. We can take the same exception object that we caught, and throw that same exception object:
public void deleteFiles(Path[] files) throws IOException { for (Path f : files) { try { Files.delete(f); } catch (IOException ioex) { System.err.println("Warning: failed to delete " + f); throw ioex; } } }Declaring that we throw an unchecked exception
We don't have to declare that our method throws an unchecked exception such as IllegalArgumentException. But occasionally we might want to as a hint to the programmer that it is a common error that a program may need to deal with in the normal course of its duties.
There are examples of this in the standard Java API libraries. The Integer.parseInt() method declares that it throws NumberFormatException. Technically speaking, NubmerFormatException is a subclass of IllegalArgumentException, which we have already said is an unchecked exception— so the method need not have declared it in its throws clause. But by declaring that parseInt() throws a NumberFormatException, this forces the programmer to have to consider this common error condition rather than "forgetting" about it.
Recasting an exception
The fact that the programmer is forced to deal with checked exceptions can be useful in cases where we don't want to forget to handle an error. But conversely, they can be overly "fussy" in some cases. The reality is that we will sometimes call methods that declare that they throw exceptions for errors that will basically never occur— or if they did, there would be little realistically that could be done to recover from the error. For example, when opening a configuration file that is absolutely required for our program to start up, we are forced to deal with an IOException in the event of the file not being present or openable. What do we do in that case?
A pattern that we sometimes resort to is "recasting". We can catch the checked exception and throw an unchecked RuntimeException in its place. The RuntimeException constructor allows us to pass in the original exception as a 'cause':
public void initApplication() { try { readConfig(); } catch (IOException ioex) { throw new RuntimeException("Fatal error: config file not found", ioex); } }In a simple command-line program with no other outer try/catch block, throwing an uncaught exception like this will terminate the application. In a more complex multithreaded program, it would pass control back to the thread's outer exception handler (see uncaught exception handlers).
For more information and examples of recasting, see: recasting exceptions.
Exceptions with lambdas
The technique of recasting is often used when we need to throw a checked exception from within a lambda expression. Although lambda expressions can throw exceptions, the standard standard functional interfaces such as Function do not declare that they throw any exceptions.
When to catch and when to throw?
When dealing with exceptions, a key question the programmer must ask is: should I catch the exception 'immediately' or throw it back up to the caller. There is no single right or wrong answer to this: the decision will usually depend on which code is best place to actually deal with the error. In some cases, an exception deep down in some long running process might indicate a "stop the world" issue that means the enire process has to be halted. In other cases, it might be a completely ignorable, or may simply require one item being processed to be marked in error.
For more discussion, see: Exceptions: when to catch and when to throw?.
Some commonly thrown exceptions
There are certain unchecked exceptions that it is common and good practice to throw at the beginning of a method:
IllegalArgumentException If your method only accepts arguments within a particular range, e.g. only positive numbers, then you should check for invalid parameters and throw an IllegalArgumentException. For example: public int calculateFactorial(int n) { if (n < 0) throw new IllegalArgumentException("n must be positive"); if (n >= 60) throw new IllegalArgumentException("n must be < 60"); ... } NullPointerException If you know that a parameter to your method cannot be null, then it is best to explicitly check for null and throw a NullPointerException. That way, the problem is detected "there and then", rather than at some mysterious point further down when part of your code tries to access the object in question. IllegalStateException This one is a little less common, but is useful a method relies on a previous method having been called. For example, if your object requires its initialise() method to be called before other methods, then you can set a flag inside initialise(), and throw an IllegalStateException if initialise() hasn't been called: private boolean initted; public void initialise() { // ... initted = true; } public void doSomething() { if (!initted) throw new IllegalStateException("Object not initialised"); } UnsupportedOperationException This exception is designed for cases where you override an abstract class or implement an interface, but don't want or can't to implement certain methods. It is used by various classes of the Java Collections Framework. Ideally, your interface or method should also provide a means for the caller to determine in advance whether it expects the given operation to be supported. RuntimeException and InternalError As alluded to above, these essentially mean "that should never happen and I don't know what to do if it does", with different degrees of seriousness. You basically want the application to "bomb out" of whatever it's doing at that moment. If essentially the application can go on working after the unexpected condition, throw a RuntimeException. Throw an InternalError in cases where "this is a very serious unexpected condition": the application is not expected to continue working and should shut down as soon and safely as possible. These exceptions are useful with the technique of recasting, where we turn a normal exception into another that represents a serious condition.As mentioned above, many other exceptions are regular "checked" exceptions (see the exception hierarchy for more details), which means that if your method throws it, you will have to declare it with throws in the method signature:
public void processFile(File f) throws IOException { if (f.length() > MAX_LENGTH) throw new IOException("File too big"); ... }If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants. Follow @BitterCoffey
Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.
Tag » How To Throw Exception In Java
-
How To Throw Exceptions In Java - Rollbar
-
How To Use The Throws Keyword In Java (and When To Use ... - Rollbar
-
How To Throw Exceptions (The Java™ Tutorials > Essential Java ...
-
Java Throw Exception - Javatpoint
-
Throw And Throws In Java - GeeksforGeeks
-
Try, Catch, Throw And Throws In Java - GeeksforGeeks
-
How To Throw An Exception In Java | Webucator
-
How To Throw Exception In Java With Example
-
How To Throw An Exception In Java - Linux Hint
-
How Can I Raise An Error In If-else Function In Java - Stack Overflow
-
Java Throws Keyword - W3Schools
-
Java Throw And Throws Keyword - Programiz
-
How To Throw Exceptions In Java - The Differences Between Throw ...
-
Types Of Exceptions In Java - Stackify