0% found this document useful (0 votes)
72 views11 pages

Hour 18. Handling Errors in A Program

This document discusses handling errors in Java programs. It begins by explaining that errors are a natural part of the software development process. There are two types of problems that can occur: exceptions, which signal unusual events, and errors, which signal interpreter problems. The document then focuses on exceptions, explaining how to catch and handle exceptions using try-catch blocks to prevent programs from crashing. It provides examples of catching specific exception types as well as catching multiple exception types within a single try-catch block.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
72 views11 pages

Hour 18. Handling Errors in A Program

This document discusses handling errors in Java programs. It begins by explaining that errors are a natural part of the software development process. There are two types of problems that can occur: exceptions, which signal unusual events, and errors, which signal interpreter problems. The document then focuses on exceptions, explaining how to catch and handle exceptions using try-catch blocks to prevent programs from crashing. It provides examples of catching specific exception types as well as catching multiple exception types within a single try-catch block.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 11

Hour 18.

Handling Errors in a Program

No subject in this book is less popular than the one you're about to tackle: errors.

Errors—the various bugs, blunders, typos, and other problems that stop a program from running
successfully—are a natural part of the software development process. "Natural" is probably the
kindest word that has ever been used to describe them—in my own Java programming, when I can't
find the cause of an elusive error that keeps my program from working, I use words that would make
a gangsta rapper blush.

Some errors are flagged by the compiler and prevent you from creating a class. Others are noted by
the interpreter in response to a problem that keeps it from running successfully.

There are two kinds of problems you will encounter in Java:

 Exceptions— Events that signal an unusual circumstance has taken place as a program runs

 Errors— Events that signal the interpreter is having problems that may be unrelated to your
program

During this hour, we'll explore exceptions as the following topics are discussed:

 How to use methods that cause exceptions

 How to respond to exceptions in your Java programs

 How to create methods that ignore an exception, leaving it for another class to handle

 How to create your own exceptions

You'll also learn about a new feature of version 1.4 that helps keep errors out of your programs:
assertions.

Exceptions

Although you are just learning about them now, you have probably become well-acquainted with
exceptions during the previous hours of this book. These errors turn up when you write a Java
program that compiles successfully but encounters a problem when it runs.

For example, a common programming mistake is to refer to an element of an array that doesn't exist,
as in the following statements:

String[] greek = { "Alpha", "Beta", "Gamma" };


System.out.println(greek[3]);

In this example, the String array has three elements. Because the first element in an array is numbered
0 rather than 1, the first element is greek[0], the second is greek[1] and the third is greek[2]. The
statement to display the contents of greek[3] is erroneous, because that element does not exist.

The above statements will compile successfully, but when you run the program, the Java interpreter
will halt with a message such as the following:

Exception in thread "main" java.lang.ArrayIndexOutBoundsException


at SampleProgram.main(SampleProgram.java:4)

This message indicates that the application has generated an exception, which the interpreter made
note of by displaying an error message and stopping the program.

This error message includes a reference to a class called ArrayIndexOutOfBoundsException in the


java.lang package. This class is an exception, an object that is created to make note of an exceptional
circumstance that has taken place in a Java program.

When a Java class encounters an exception, it alerts users of the class to the error. In this example, the
user of the class is the Java interpreter.

Note

Two terms that are used to describe this process are throw and catch. Classes and methods can throw
exceptions to alert others that they have occurred. These exceptions can be caught by other classes,
methods, or the Java interpreter.

All exceptions are subclasses of Exception, another class in the java.lang package. The
ArrayIndexOutOfBoundsException does what you would expect—it lets you know you have used an
array element that isn't within the array's boundaries.

There are hundreds of exceptions in Java. Many of them indicate a problem that can be fixed with a
change in your program, such as the array exception. These are comparable to compiler errors—once
you correct the situation, you don't have to concern yourself with the exception any longer.

Other exceptions must be dealt with every time a program runs by using five new statements: try,
catch, finally, throw, and throws.

Catching Exceptions in a try-catch Block

Up to this point, you have dealt with exceptions by fixing the problem that caused them. There are
times you either can't deal with an exception like this or want to handle them within a Java class.
As an introduction to why this is useful, enter the short Java application in Listing 18.1 and save it as
SumNumbers.java.

Example 18.1. The Full Text of SumNumbers.java

1: class SumNumbers {
2: public static void main(String[] arguments) {
3: float sum = 0;
4: for (int i = 0; i < arguments.length; i++)
5: sum = sum + Float.parseFloat(arguments[i]);
6: System.out.println("Those numbers add up to " + sum);
7: }
8: }

You can compile this application successfully. The SumNumbers application takes one or more
numbers as command-line arguments, adds all of them up, and displays the total.

Because all command-line arguments are represented by strings in a Java application, the program
must convert them into floating-point numbers before adding them together. The Float.parseFloat()
class method in Line 5 takes care of this, adding the converted number to a variable named sum.

Run the application with the following command (or use another Java tool where you can specify the
same seven numeric arguments):

java SumNumbers 8 6 7 5 3 0 9

The application will display the following output:

Those numbers add up to 38.0

Run the program several times with different numbers as arguments. It should handle all of them
successfully, which might make you wonder what this has to do with exceptions.

To see the relevance, run the SumNumbers application with the following command:

java SumNumbers 1 3 5x

The third argument in this example contains a typo—there shouldn't be an x after the number 5. The
SumNumbers application has no way to know this is a mistake, so it tries to add 5x to the other
numbers, causing the following exception to be displayed:

Exception in thread "main" java.lang.NumberFormatException: 5x


at java.lang.FloatingDecimal.readJavaFormatString(Unknown source)
at java.lang.Float.parseFloat(Unknown source)
at SumNumbers.main(SumNumbers:5)

This message is informative to the programmer developing the application, but it's not something you
would want a user to see. Java programs can take care of their own exceptions by using a try-catch
block.

This block statement takes the following form:

try {
// statements that might cause the exception
} catch (Exception e) {
// what to do when the exception occurs
}

A try-catch block should be used with any exception that you want a program to handle. The
Exception object that appears in the catch statement should be one of two things:

 The class of the exception that might occur

 A superclass of several different kinds of exceptions that might occur

The try section of the try-catch block should contain the statement or statements that might throw an
exception. In the SumNumbers application, the call to the Float.parseFloat() method in Line 5 will
throw a NumberFormatException whenever it is used to convert a non-numeric string to a floating-
point value.

To improve the SumNumbers application so that it never stops running with this kind of error, you
can use a try-catch block that deals with this exception.

Open your text editor and create an application called NewSumNumbers.java from Listing 18.2.

Example 18.2. The Full Text of NewSumNumbers.java

1: class NewSumNumbers {
2: public static void main(String[] arguments) {
3: float sum = 0;
4: for (int i = 0; i < arguments.length; i++) {
5: try {
6: sum = sum + Float.parseFloat(arguments[i]);
7: } catch (NumberFormatException e) {
8: System.out.println(arguments[i] + " is not a number.");
9: }
10: }
11: System.out.println("Those numbers add up to " + sum);
12: }
13: }

After you save and compile the application, run it with a non-numeric command-line argument along
with a few numbers, such as the following:

java NewSumNumbers 1 3 5x

Running it with these arguments produces the following output:

5x is not a number
Those numbers add up to 4.0

The try-catch block in Lines 5–9 deals with NumberFormatException errors that are thrown by the
Float.parseFloat() method. These exceptions are caught within the NewSumNumbers class, which
displays an error message for any argument that is not a number.

Because the exception is handled within the class, the Java interpreter does not display an error
message when something like 5x is used as a command-line argument.

You can often deal with problems related to user input and other unexpected data by using try-catch
blocks.

Note

You can also use try and catch to deal with errors that could be fixed by making some changes to your
program, such as the ArrayIndexOutOfBoundsException problem that was described earlier this hour.
This isn't recommended—the easiest solution is to change your program so the error never occurs.

Catching Several Different Exceptions

try-catch blocks can be used to handle several different kinds of exceptions, even if they are thrown
by different statements.

Listing 18.3 contains an application called DivideNumbers that takes two integer arguments from the
command-line and uses them in a division expression.
This application must be able to deal with two potential problems in user input:

 Non-numeric arguments

 Division by zero

Example 18.3. The Full Text of DivideNumbers.java

1: class DivideNumbers {
2: public static void main(String[] arguments) {
3: if (arguments.length == 2) {
4: int result = 0;
5: try {
6: result = Integer.parseInt(arguments[0]) /
7: Integer.parseInt(arguments[1]);
8: System.out.println(arguments[0] + " divided by " +
9: arguments[1] + " equals " + result);
10: } catch (NumberFormatException e) {
11: System.out.println("Both arguments must be numbers.");
12: } catch (ArithmeticException e) {
13: System.out.println("You cannot divide by zero.");
14: }
15: }
16: }
17: }

Compile the application and try it out with some integers, floating-point numbers, and non-numeric
arguments.

The if statement in Line 3 checks to make sure that two arguments were sent to the application. If not,
the program exits without displaying anything.

The DivideNumbers application performs integer division, so the result will be an integer. This isn't
going to be as accurate as division using floating-point numbers—in integer division, 5 divided by 2
equals 2, not 2.5.

If you use a floating-point or non-numeric argument, a NumberFormatException will be thrown by


Lines 6–7 and caught by Lines 10–11.
If you use an integer as the first argument and a zero as the second argument, a ArithmeticExpression
will be thrown in Lines 6–7 and caught by Lines 12–13.

Handling Something After an Exception

When you are dealing with multiple exceptions by using try and catch, there are times when you want
the program to do something at the end of the block whether an exception occurred or not.

You can handle this by using a try-catch-finally block, which takes the following form:

try {
// statements that might cause the exception
} catch (Exception e) {
// what to do when the exception occurs
} finally {
// statements to execute no matter what
}

The statement or statements within the finally section of the block will be executed after everything
else in the block, even if an exception occurs.

One place this is useful is in a program that reads data from a file on disk, which you will do in Hour
20, "Reading and Writing Files." There are several ways an exception can occur when you are
accessing data—the file might not exist, a disk error could occur, and so on. If the statements to read
the disk are in a try section and errors are handled in a catch section, you can close the file in the
finally section. This makes sure that the file will be closed whether or not an exception was thrown as
it was read.

Throwing Exceptions

When you call a method of another class, that class can control how the method is used by throwing
exceptions.

As you make use of the classes in the Java class library, the compiler will often display a message
such as the following:

NetReader.java:14: unreported exception java.net.MalformedURLException; must be


caught or declared to be thrown

Whenever you see an error stating that an exception "must be caught or declared to be thrown," it
indicates that the method you are trying to use throws an exception.
Any class that calls these methods, such as an application that you write, must do one of the following
things:

 Handle the exception with a try-catch block.

 Throw the exception.

 Handle the exception with a try-catch block and then throw it.

Up to this point in the hour, you have seen how to handle exceptions. If you would like to throw an
exception after handling it, you can use a throw statement followed by the exception object to throw.

The following statements handle a NumberFormatException error in a catch block and then throw the
exception:

try {
principal = Float.parseFloat(loanText) * 1.1F;
} catch (NumberFormatException e) {
System.out.println(arguments[i] + " is not a number.");
throw e;
}

When you throw an exception in this manner, it generally means that you have not done everything
that needs to be done to take care of the exception.

An example of where this might be useful: Consider a hypothetical program called


CreditCardChecker, an application that verifies credit card purchases. This application uses a class
called CheckDatabase, which has the following job:

1. Make a connection to the credit card lender's computer.

2. Ask that computer if the customer's credit card number is valid.

3. Ask the computer if the customer has enough credit to make the purchase.

As the CheckDatabase class is doing its job, what happens if the credit card lender's computer doesn't
answer the phone at all? This kind of error is exactly the kind of thing that the try-catch block was
designed for, and it is used within CheckDatabase to handle connection errors.

If the CheckDatabase class handles this error by itself, the CreditCardChecker application won't know
that the exception took place at all. This isn't a good idea—the application should know when a
connection cannot be made so it can report this to the person using the application.
One way to notify the CreditCardChecker application is for CheckDatabase to catch the exception in a
catch block, then throw it again with a throw statement. The exception will be thrown in
CheckDatabase, which must then deal with it like any other exception.

Exception handling is a way that classes can communicate with each other in the event of an error or
other unusual circumstance.

Ignoring Exceptions

The last technique that will be covered today is the laziest: how to ignore an exception completely.

A method in a class can ignore exceptions by using a throws clause as part of the method definition.

The following method throws a MalformedURLException, an error that can occur when you are
working with World Wide Web addresses in a Java program:

public void loadURL(String address) throws MalformedURLException {


URL page = new URL(address);
loadWebPage(page);
}

The second statement in this example, URL page = new URL(address); creates a URL object, which
represents an address on the Web. The constructor method of the URL class throws a
MalformedURLException to indicate that an invalid address was used, so no object can be
constructed. The following statement would cause one of these exceptions to be thrown:

URL source = new URL("http:www.java24hours.com");

The string http:www.java24hours.com is not a valid URL. It's missing some punctuation—two slash
characters (//).

Because the loadURL() method has been declared to throw MalformedURLException errors, it does
not have to deal with them inside the method. The responsibility for handling this exception falls to
any class that calls the loadURL() method.

Assertions

Sun Microsystems did something in Java 2 version 1.4 that hasn't happened often in the history of the
language: It added a new keyword, assert.
The assert keyword enables Java programmers to use assertions, a technique that's supposed to
improve the reliability of software. An assertion is a Boolean true-or-false expression that represents
something that should be true at that spot in the program. Here's an example:

assert speed > 55;

This statement asserts that the speed variable has a value greater than 55. It's another way for a
programmer to say, "I expect speed to be greater than 55 at this position, and if it isn't, my program
would be completely FUBAR."

FUBAR is an acronym popular among computer programmers that means "fouled up beyond all
recognition" or "fouled up beyond all repair." A saltier version that uses a different F word is even
more popular.

Assertions are a way to ensure that a program is running as expected.

The assert keyword must be followed by something that produces a Boolean value: an expression, a
boolean, or a method that returns a boolean. Three examples:

assert pointX = 0;

assert endOfFileReached;

assert network.noLongerConnected();

If the expression used with the assert keyword is false, an AssertionError exception will be thrown.
You can make these errors more meaningful by specifying an error message in an assert statement.
Add a colon and text at the end, as in this example:

assert temperature > 2200 : "Core breach in Sector 12!";

If you're using the SDK interpreter, here's how it responds to an AssertionError exception:

Exception in thread "main" java.lang.AssertionError: Core breach in Sector 12!


at Nuke.power(Nuke.java:1924)

Assertions are offered in Java 1.4, but are turned off by default in the SDK (and presumably other
tools as well).

SDK users must use command-line arguments to turn on assertion support. To compile a class that
contains assert statements, use the -source 1.4 option, as in the following example:

javac -source 1.4 Nuke.java


The -source 1.4 option causes the compiler to support assertions in the class file (or files) that it
produces. An error will result if you try to compile a program that contains assert statements but do
not use this option.

You must also enable assertions when running a Java class with the SDK interpreter. The easiest way
to do this is to use the -ea argument, which enables assertions for all classes (except those that are part
of the Java class library):

java -ea Nuke

To enable assertions only in one class, follow -ea with a colon and the name of the class, as in this
example:

java -ea:Nuke Nuke

To enable assertions only in one package, follow -ea with a colon and the name of the package:

java -ea:com.prefect.power Nuke

Summary

Now that you have put Java's exception handling techniques to use, I hope the subject of errors is a
little more popular than it was at the beginning of the hour.

You can do a lot with these techniques:

 Catch an exception and deal with it

 Ignore an exception, leaving it for another class or the Java interpreter to take care of

 Catch several different exceptions in the same try-catch block

 Throw your own exception

Managing exceptions in your Java programs makes them more reliable, more versatile, and easier to
use, because you don't display any cryptic error messages to people who are running your software.

Once you're comfortable handling errors, you can even use assertions to create more of them—as a
safeguard against the times when your assumptions about a program are not correct.

You might also like