Exception Handling in Java: Understanding throws with Example
Let’s
look at the example shown here so we can better understand this feature.
|
import java.io.*; import java.net.*; public class
CentralizedExceptionHandlerApp { private static
BufferedReader reader = null; public static void
main(String[] args) { String urlStr =
null; try { CentralizedExceptionHandlerApp
app =
newCentralizedExceptionHandlerApp(); app.openDataFile("data.txt"); app.readData(); reader.close(); } catch
(IOException e) { System.out.println("Error
closing file"); } catch
(Exception ex) { System.out.println("Unknown
error: " + ex.getMessage()); } } void openDataFile(String
fileName) { try { reader =
new BufferedReader(new FileReader(fileName)); } catch
(FileNotFoundException e) { System.out.println("Specified
file not found"); } } void readData() { String str; try { while
((str = reader.readLine()) != null) { int
n = Integer.parseInt(str); System.out.println(n); } } catch
(IOException e) { System.out.println("Error
while reading data"); } catch
(NumberFormatException ne) { System.out.println("Invalid
number format, skipping rest"); } } } |
A
quick look at the program tells us that the CentralizedExceptionHandlerApp
class has three methods:
·
main()
·
openDataFile()
·
readData()
All
three methods have some sort of exception-handling code. If we do a little more
observation, we will also realize that almost 50 percent of the total source
code consists of exception handling. So why not gather all the exception
handling into one place and make our methods cleaner? The modified program is given
here:
|
import java.io.*; import java.net.*; public class
ModifiedCentralizedExceptionHandlerApp { private static
BufferedReader reader = null; public static void
main(String[] args) { String urlStr =
null; try { ModifiedCentralizedExceptionHandlerApp
app =
new ModifiedCentralizedExceptionHandlerApp(); app.openDataFile("data.txt"); app.readData(); reader.close(); } catch
(FileNotFoundException e) { System.out.println("Specified
file not found"); } catch
(IOException e) { System.out.println("Error
closing file"); } catch
(NumberFormatException ne) { System.out.println("Invalid
number format, skipping rest"); } catch
(Exception ex) { System.out.println("Unknown
error: " + ex.getMessage()); } } void openDataFile(String
fileName) throws FileNotFoundException { reader = new
BufferedReader(new FileReader(fileName)); } void readData() throws
IOException, NumberFormatException { String str; while ((str =
reader.readLine()) != null) { int n =
Integer.parseInt(str); System.out.println(n); } } } |
Examine this code and we will realize that the two methods
·
openDataFile
·
readData
do
not contain any exception handlers. However, the code within these methods may
still generate errors at runtime. So, who handles those? Note the use of the throws
keyword in their declarations.
· The openDataFile method is
declared to throw a FileNotFoundException. This means that if such an error
occurs in the body of this method, it will be thrown to its caller, asking the
caller to take care of it, if it wants to do so.
· Similarly, the method
readData throws two types of exceptions: IOException and NumberFormatException.
If these errors occur at runtime, they will be passed on to the caller for
further processing.
· Now, let’s look at the main method.
Here, we will find several catch blocks. In fact, some of these catch blocks
came from our earlier definitions of the openDataFile and readData methods.
Therefore, the errors thrown by these methods are now handled in the main
method.
· This makes our code cleaner.
It allows us to centralize exception handling and pass on the
exception-handling responsibility to somebody higher up the calling stack.
Throwing
Multiple Exceptions
We
may cause a method to throw more than one type of exception by listing all the
desired exception types in the throws clause, separated by commas. This is what
we have seen in the modified definition of our readData method from the above
example:
void readData() throws IOException, NumberFormatException {
Here,
the method readData throws two types of exceptions to its caller. Therefore, it
need not provide exception handlers for either of these two types. However, if
the code inside readData can generate an exception of any other type, which is
also a checked exception, readData must provide an internal exception handler.
The exceptions of the unchecked type need not be caught but may result in
abnormal program termination.
This indicates that a method may handle some of the errors itself and leave the handling of specialized exceptions to its caller.
Leave Comment
1 Comments