|
JAVA
Exceptions
- Because Java is robust there are certain runtime errors java does
not like, i.e. arithmetic exceptions, NullPointerException, etc.
InputMismatchException.
Java Text Books
Handling Exceptions
-
In a GUI, exceptions will cause a program to
terminate.
-
Use exception handlers (try/catch) to prevent
program termination because these happen at runtime not compile time. Let
the user know what is incorrect and recover with re-prompting or setting
defaults.
-
Use try, catch, and finally blocks. There is
also an Exception class that can be used to reuse the classes.
Minimum try/catch Syntax
-
Curly braces are absolutely required.
-
"try" is the code to attempt.
-
"catch” handles the exception, if the
exception happens catch redoes the steps necessary.
Checked and Unchecked Exceptions
-
Two kinds of exceptions, checked and
unchecked.
-
Anything from a runtime exception is an
unchecked exception. Meaning you don't have to provided a try/catch block.
Subclasses of Error or RuntimeException.
Exception Class Methods
- getMessage indicates cause of the exception
- toString - indicates cause
- printStackTrace print line number of cod that caused the exception.
- All statements can be put inside the catch block.
|
Catching a
NumberFormatException
import
javax.swing.JOptionPane;
public class DialogBoxInput
{
public static void main( String [] args )
{
int n = 0; // declare and initialize variable
// prompt for input
String s = JOptionPane.showInputDialog( null,
"Enter an integer" );
System.out.println( "You entered " + s );
try
{
// attempt to convert the String to an int
n = Integer.parseInt( s );
System.out.println( "Conversion was
successful." );
}
catch ( NumberFormatException nfe )
{
System.out.println( "Sorry. incompatible
data." );
System.out.println( "\nOutput from
getMessage: \n"
+ nfe.getMessage( ) );
System.out.println( "\nOutput from toString:
\n"
+ nfe.toString( ) );
System.out.println( "\nOutput from
printStackTrace: " );
nfe.printStackTrace( );
}
System.out.println( "\nn is " + n );
}
} |
- If there are no exceptions the catch block does
not get executed.
Flow of control goes to the matching catch block with the object type of the
exception. parseInt throws the object of NumberFormatException and flow of
control moves to this block. You need to initialize 'n' first because the flow
of control will go to the catch without assigning anything to 'n'.
Recovering from an Exception
|
import javax.swing.JOptionPane;
public class DialogBoxInput
{
public static void main( String [] args )
{
// declare and initialize
variables that will be
// assigned values in the try
block
int n = 0;
boolean goodInput = false; //
flag variable
// priming read
String s =
JOptionPane.showInputDialog( null,
"Enter an integer" );
do
{
try
{
//
attempt to convert the String to an int
n =
Integer.parseInt( s );
goodInput
= true;
}
catch (
NumberFormatException nfe )
{
s =
JOptionPane.showInputDialog( null,
s + " is not an integer. "
+ "Enter an integer" );
}
} while ( !goodInput );
JOptionPane.showMessageDialog(
null, "The integer is " + n );
}
} |
Catching multiple exceptions
- Any statement that may throw an exception
can be in a try block but you have to put the catch blocks - You have
to remember the hierarchical tree, IndexOutOfBound is a subclass of further
classes and you can put in a very general exception, i.e. you can just catch
Exception. So start with a specific exception in your catch blocks and then
move up the hierarchy for later catches. - Only one catch block will be
executed, and it will be the same object type as the one that was thrown.
try/catch/finally syntax
- finally executes no matter what. If an
exception gets thrown, finally executes after the catch. - How often is
finally actually used in practice? Finally is good for closing opened
resources. This is a very good practice to use.
|
import javax.swing.JOptionPane;
public class Divider
{
public static void main( String [] args )
{
int divisor = 0;
int quotient = 0;
int dividend = 100;
boolean goodInput = false;
String s =
JOptionPane.showInputDialog( null,
"Enter an integer" );
do
{
try
{
// convert the String to an integer
divisor =
Integer.parseInt( s );
quotient
= dividend / divisor;
allOK =
true;
}
catch (
NumberFormatException nfe )
{
s =
JOptionPane.showInputDialog( null,
s +
" not an integer. "
+ "Enter an integer Please" );
}
catch (
ArithmeticException ae )
{
s =
JOptionPane.showInputDialog( null,
"Divisor cannot be 0. "
+ "Enter an integer Non Zero divisor" );
}
} while ( ! allOK);
JOptionPane.showMessageDialog(
null,
"The result is " + quotient );
}
} |
Line divisor =
Integer.parseInt( s )may generate a NFE and get the catch on
catch (
NumberFormatException
nfe ). If the statement generates and AE then compiler hits
catch ( ArithmeticException ae ) catch and
prompts user again.
User-Defined Exceptions
- EmailAddress class. We already have
IllegalArgumentException so extend this class to get an email class.
Extending an Existing Exception.
Throwing an exception
public class IllegalEmailException extends
IllegalArgumentException
{
public IllegalEmailException( String message
)
{
super( message );
}
Construction invokes IllegalArgumentException
|
public class EmailAddress
{
public static final char AT_SIGN = '@';
private String email;
public EmailAddress( String newEmail )
throws IllegalEmailException
{
if ( newEmail.indexOf( AT_SIGN )
!= - 1 )
email =
newEmail;
else
throw new
IllegalEmailException
( "Email address does not contain " + AT_SIGN );
}
public String getHost( )
{
int index = email.indexOf(
AT_SIGN );
return email.substring( index +
1, email.length( ) );
}
}
|
Statement throw new IllegalEmailException throws
exception of IllegalEmailException using the throw key word. This will be
obtained by running a catch for IEE in try/catch block.
If a method throws an exception it must be thrown with the "throw" keyword by
creating a new object to throw that the JVM can match.
|
import
java.util.Scanner; public class EmailChecker { public
static void main( String [] args )
{
Scanner scan = new Scanner( System.in );
System.out.print( "Enter your web hosting email address > " );
String myEmail = scan.next( );
try
{
EmailAddress address = new EmailAddress( myEmail );
System.out.println( "Your host is " + address.getHost( ) );
}
catch( IllegalEmailException iee )
{
System.out.println( iee.getMessage( ) );
} } } |
Sometimes the flow of control is changed
by the exception. In general this is bad idea. Also try/catch are costly
so if you can error check with if/else you are better off. However, with
a database connection, you can't control how many ways this can fail so
a try/catch makes sense here. But if you know the failure (ie, checking
a substring) then if/else makes sense. A a general rule, if you are
using if/else and the code looks like spaghetti it's time to use
try/catch. It all depends. If performance is not an issue, use
try/catch. But don't use try/catch to control flow.
|
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.FileNotFoundException;
import java.io.EOFException;
import java.io.IOException;
public class ReadingObjects
{
public static void main( String [] args )
{
try
{
FileInputStream fis = new
FileInputStream( "objects " );
ObjectInputStream ois = new
ObjectInputStream( fis );
try
{
while ( true )
{
//
read object, type cast returned object to FlightRecord
FlightRecord2 temp = ( FlightRecord2 ) ois.readObject( );
//
print the FlightRecord2 object read
System.out.println( temp );
}
} // end inner try block
catch( EOFException eofe )
{
System.out.println(
"End of the file reached" );
}
catch(
ClassNotFoundException cnfe )
{
System.out.println(
cnfe.getMessage( ) );
}
finally
{
System.out.println( "Closing file" );
ois.close( );
}
} // end outer try block
catch( FileNotFoundException fnfe )
{
System.out.println(
"Unable to find objects" );
}
catch( IOException ioe )
{
ioe.printStackTrace( );
}
}
}
|
- The “while” loop runs forever until the endOfFile exception ends the loop.
|