Download Notes - Tom Kleen

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Chapter 14: Exception Handling and Text
I/O
Run time error: A run-time error occurs when a program is running and it is given an
instruction that is impossible for it to carry out. Some obvious examples are
(1) Dividing by 0 (although Java allows division by 0 when using floats or doubles, but not
integers).
(2) Trying to open a file that doesn't exist or read past the end of an existing file.
(3) Trying to convert a non-numeric string to a numeric value.
(4) Trying to access an element of an array that doesn't exist (because the array index is
either less than 0 or it is greater than or equal to the number of elements in the array).
14.2 Exception-Handling Overview
Consider the following program (Listing 14.1):
import java.util.Scanner;
public class Quotient {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Prompt the user to enter two integers
System.out.print("Enter two integers: ");
int number1 = input.nextInt();
int number2 = input.nextInt();
System.out.println(number1 + " / " + number2 + " is " + (number1 /
number2));
}
}
Try to run it with the second integer equal to 0. The program blows up.
There are two solutions to the problem. One solution is to protect the offending statement
by putting it in an if statement (Listing 14.2).
import java.util.Scanner;
public class QuotientWithIf {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Prompt the user to enter two integers
System.out.print("Enter two integers: ");
Document1
1
5/3/2017
int number1 = input.nextInt();
int number2 = input.nextInt();
if (number2 != 0)
System.out.println(number1 + " / " + number2 + " is " +
(number1 / number2));
else
System.out.println("Divisor cannot be zero ");
}
}
Yet another way is to exit the program when an error occurs (Listing 14.3). This is a bad
way to handle the problem because it allows the method to decide to terminate the
program, a decision that probably should be left to the main program:
import java.util.Scanner;
public class QuotientWithMethod
{
public static int quotient(int number1, int number2)
{
if (number2 == 0)
{ System.out.println("Divisor cannot be zero");
System.exit(1);
}
return number1 / number2;
}
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
// Prompt the user to enter two integers
System.out.print("Enter two integers: ");
int number1 = input.nextInt();
int number2 = input.nextInt();
int result = quotient(number1, number2);
System.out.println(number1 + " / " + number2 + " is "
+ result);
}
System.out.println("Execution continues ...");
}
}
Document1
2
5/3/2017
A better way is to do something called "throwing" an exception, and allowing the main
program to decide what to do about it.
import java.util.Scanner;
public class QuotientWithException {
public static int quotient(int number1, int number2) {
if (number2 == 0)
throw new ArithmeticException("Divisor cannot be zero");
return number1 / number2;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Prompt the user to enter two integers
System.out.print("Enter two integers: ");
int number1 = input.nextInt();
int number2 = input.nextInt();
try {
int result = quotient(number1, number2);
System.out.println(number1 + " / " + number2 + " is "
+ result);
}
catch (ArithmeticException ex) {
System.out.println("Exception: an integer " +
"cannot be divided by zero ");
}
System.out.println("Execution continues ...");
}
}
14.3 Exception Handling Advantages
Exceptions allow methods to avoid dealing with an error by passing it "up" to the caller
(which can also pass it "up" to its caller, etc.). If it didn't work this way, then the exception
would have to be handled where it occurs. The problem with this is that the method where
the exception occurs may not know what to do to handle it!
14.6 The finally Clause
If there is some code that you want to be executed whether an exception occurs or not, you
can add a finally clause.
try
{
Document1
3
5/3/2017
statements;
}
catch (Exception e)
{
handle the exception;
}
finally
{
final statements;
}
Common use: to make sure that a file gets closed, regardless of whether an error occurred
or not.
14.7 When to Use Exceptions
Only throw exceptions when you cannot handle the problem in the method where the
exception occurred.
Not this:
try
{
System.out.println (refVar.toString());
}
catch(NullPointerException ex)
{
System.out.println ("refVar is null");
}
Use this instead:
if (refVar != null)
System.out.println (refVar.toString());
else
System.out.println ("refVar is null");
Text Files: Using a Scanner object for input
Reading an input file with multiple data items on each line.
Let's create a program that will take text that has "tokens" on it (separated by white
space):




First name
Middle initial
Last name
Score
Document1
4
5/3/2017
And split the line into a name and a score. The easiest way to do this is to use the Scanner
object, which splits a string into "tokens" delimited by white space (spaces, tabs, carriage
returns).
Code to read text strings and ints into an array of strings and ints
Note that this can be done with a file using the same code except for the line that creates the new
Scanner.
public static void readStringsAndIntsFile() throws Exception
{
Scanner input = new Scanner("John T Smith 90 Eric K Jones 85");
String[] firstNname = new String[10];
String[] middleInitial = new String[10];
String[] lastName = new String[10];
int[] score = new int [10];
int i = 0;
while (input.hasNext())
{ firstName[i] = input.next();
middleInitial[i] = input.next();
lastName[i] = input.next();
score[i] = input.nextInt();
i++;
}
int lineCount = i;
// Now print the array
System.out.println ("\nNames and Scores");
for (i=0; i<lineCount; i++)
System.out.println (String.format("%15s %1s %15s %5d",
firstName[i], middleInitial[i], lastName[i], score[i]));
}
You can define your own delimiter character(s). Make the following changes:
Scanner input = new Scanner("John/T/Smith/90/Eric/K/Jones/85");
// Put delimiter characters in square brackets
input.useDelimiter("[/]");
You can check for multiple delimiter characters:
Scanner input = new Scanner("John T/Smith^90 Eric/K^Jones/85");
// Put delimiter characters in square brackets: space, slash, and right
bracket
input.useDelimiter("[ /^]");
You can also use control characters (like tab, carriage return):
Document1
5
5/3/2017
Scanner input = new Scanner("John T/Smith^90\nEric\tK\rJones/85");
// Put delimiter characters in square brackets: space, slash, caret,
newline, tab, return
input.useDelimiter("[ /^\n\t\r]");
Note that the above looks for exactly ONE of the delimiter characters. If there are two, then
the scanner assumes that there are two tokens! So if you have two blanks separating two
tokens, you MAY get an error. I have added an extra space before the word "Eric":
Scanner input = new Scanner("John T/Smith^90 Eric/K^Jones/85");
// Put delimiter characters in square brackets
input.useDelimiter("[ /^]");
This (above) generates an error only because we are now trying to read the word "Jones"
into an array of integers!
If we want to tell the scanner to treat multiple delimiters as a single delimiter (frequently
there may be many spaces between tokens), we need to put a plus sign after the list of
delimiters, like this:
Scanner input = new Scanner(
"John^T^Smith^^^^^^90 Eric\t \n\n\r
K^Jones//////85");
// Put delimiter characters in square brackets
input.useDelimiter("[ /^\t]+");
The "+" means "one or more of the preceding".
Special characters in the argument to useDelimiter:





[] anything in square brackets means "pick one"
\t = tab
\n = new line
\r = carriage return
+ = one or more of the preceding
Document1
6
5/3/2017
Text Files: Using a PrintWriter for output
The textbook recommends using a File object and a PrintWriter object to write to a text file.
Listing 14.13
public class WriteData {
public static void main(String[] args) throws Exception {
java.io.File file = new java.io.File("scores.txt");
if (file.exists()) {
System.out.println("File already exists");
System.exit(0);
}
// Create a file
java.io.PrintWriter output = new java.io.PrintWriter(file);
// Write formatted output to the file
output.print("John T Smith ");
output.println(90);
output.print("Eric K Jones ");
output.println(85);
// Close the file
output.close();
}
}
Document1
7
5/3/2017