Exceptions
No program ever works 100 percent of the time, and the designers of the Java language knew this. In this section, learn about the Java platform's built-in mechanisms for handling situations in which your code doesn't work exactly as planned.
Exception-handling basics
A special case is an occasion that happens amid program execution that disturbs the typical stream of the program's guidelines. Special case dealing with is a fundamental strategy of Java programming. You wrap your code in an attempt square (which signifies "attempt this and let me know whether it causes a special case") and utilize it to get different sorts of exemptions.
To get started with exception handling, take a look at the code in Listing 10.
Listing 10. Do you see the error?
@Test public void yetAnotherTest() { Logger l = Logger.getLogger(Employee.class.getName()); // Employee employee1 = new Employee(); Employee employee1 = null; employee1.setName("J Smith"); Employee employee2 = new Employee(); employee2.setName("J Smith"); l.info("Q: employee1 == employee2? A: " + (employee1 == employee2)); l.info("Q: employee1.equals(employee2)? A: " + employee1.equals(employee2)); } |
Notice that the
Employee
reference is set to null
. Run this code and you get the following output:
This output is telling you that you're trying to reference an object through a
null reference (pointer), which is a pretty serious development error. (You probably noticed that Eclipse warns you of the potential error with the message: Null pointer access: The variable employee1 can only be null at this location . Eclipse warns you about many potential development mistakes — yet another advantage of using an IDE for Java development.) |
Fortunately, you can use
try
and catch
blocks (along with a little help from finally
) to catch the error.Using try, catch, and finally
Listing 11 shows the buggy code from Listing 10 cleaned up with the standard code blocks for exception handling:
try
, catch
, and finally
.Listing 11. Catching an exception
@Test public void yetAnotherTest() { Logger l = Logger.getLogger(Employee.class.getName()); // Employee employee1 = new Employee(); try { Employee employee1 = null; employee1.setName("J Smith"); Employee employee2 = new Employee(); employee2.setName("J Smith"); l.info("Q: employee1 == employee2? A: " + (employee1 == employee2)); l.info("Q: employee1.equals(employee2)? A: " + employee1.equals(employee2)); } catch (Exception e) { l.severe("Caught exception: " + e.getMessage()); } finally { // Always executes } } |
Together, the
try
, catch
, and finally
blocks form a net for catching exceptions. First, the try
statement wraps code that might throw an exception. In that case, execution drops immediately to the catch
block, orexception handler. When all the trying and catching is done, execution continues to the finally
block, whether or not an exception occurred. When you catch an exception, you can try to recover gracefully from it, or you can exit the program (or method).
In Listing 11, the program recovers from the error and then prints out the exception's message:
Sep 19, 2015 2:01:22 PM com.makotojava.intro.EmployeeTest yetAnotherTest SEVERE: Caught exception: null |
The exception hierarchy
The Java language incorporates an entire exception hierarchy consisting of many types of exceptions grouped into two major categories:
- Checked exceptions are checked by the compiler (meaning the compiler makes sure that they get handled somewhere in your code). In general, these are direct subclasses of
java.lang.Exception
. - Unchecked exceptions (also called runtime exceptions) are not checked by the compiler. These are subclasses of
java.lang.RuntimeException
.
At the point when a program causes a special case, you say that it tosses the exemption. A checked exemption is pronounced to the compiler by any strategy with the tosses watchword in its technique signature. Next is a comma-isolated rundown of special cases that the strategy could possibly toss amid its execution. In the event that your code calls a technique that indicates that it tosses at least one writes of exemptions, you should deal with it some way or another, or add a tosses to your strategy mark to pass that special case sort along.
At the point when an exemption happens, the Java runtime scans for a special case handler some place up the stack. On the off chance that it doesn't discover one when it achieves the highest point of the stack, it stops the program unexpectedly, as you found in Listing 10.
Multiple catch blocks
You can have various catch squares, yet they should be organized especially. On the off chance that any exemptions are subclasses of different special cases, the youngster classes are set in front of the parent classes in the request of the catch pieces. Posting 12 demonstrates a case of various special case sorts organized in their right progressive grouping.
Listing 12. Exception hierarchy example
@Test public void exceptionTest() { Logger l = Logger.getLogger(Employee.class.getName()); File file = new File("file.txt"); BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader(file)); String line = bufferedReader.readLine(); while (line != null) { // Read the file } } catch (FileNotFoundException e) { l.severe(e.getMessage()); } catch (IOException e) { l.severe(e.getMessage()); } catch (Exception e) { l.severe(e.getMessage()); } finally { // Close the reader } } |
In this example, the
FileNotFoundException
is a child class of IOException
, so it must be placed ahead of the IOException catch
block. And IOException
is a child class of Exception
, so it must be placed ahead of the Exception catch
block.try-with-resources blocks
The code in Listing 12 must declare a variable to hold the
bufferedReader
reference, and then in thefinally
must close the BufferedReader
.
Alternative, more-compact syntax (available as of JDK 7) automatically closes resources when the
try
block goes out of scope. Listing 13 shows this newer syntax.Listing 13. Resource-management syntax
@Test public void exceptionTestTryWithResources() { Logger l = Logger.getLogger(Employee.class.getName()); File file = new File("file.txt"); try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) { String line = bufferedReader.readLine(); while (line != null) { // Read the file } } catch (Exception e) { l.severe(e.getMessage()); } } |
Essentially, you assign resource variables after
try
inside parentheses, and when the try
block goes out of scope, those resources are automatically closed. The resources must implement thejava.lang.AutoCloseable
interface; if you try to use this syntax on a resource class that doesn't, Eclipse warns you.
0 coment�rios:
Post a Comment