31
Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 1 C hapter5 How to validate inputdata

Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Embed Size (px)

Citation preview

Page 1: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 1

Chapter 5

How to validate input data

Page 2: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 2

Objectives

Applied

Given an application that uses the console to get input from the user, write code that handles any exceptions that might occur.

Given an application that uses the console to get input from the user and the validation specifications for that data, write code that validates the user entries.

Given the Java code for an application that uses any of the language elements presented in this chapter, explain what each statement in the application does.

Given the output for an unhandled exception, determine the cause of the exception.

Page 3: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 3

Objectives (continued)

Knowledge

Explain what an exception is in Java.

Describe the Exception hierarchy and name two of its subclasses.

Explain what the stack trace is and how you can use it to determine the cause of an exception.

Explain how you use the try statement to catch an exception.

Explain what an exception handler is and when the code in an exception handler is executed.

Explain how you can use methods of the Scanner class to validate data.

Explain why it’s usually better to validate user entries than to catch and handle exceptions caused by invalid entries.

Page 4: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 4

Objectives (continued) Describe the two types of data validation that you’re most likely to

perform on a user entry.

Explain why you might want to use generic methods for data validation.

Page 5: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 5

Some of the classes in the Exception hierarchy Exception RuntimeException NoSuchElementException InputMismatchException IllegalArgumentException NumberFormatException ArithmeticException NullPointerException

Page 6: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 6

The console after an InputMismatchException has been thrown Enter subtotal: $100 Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:810) at java.util.Scanner.next(Scanner.java:1404) at java.util.Scanner.nextDouble(Scanner.java:2291) at InvoiceApp.main(InvoiceApp.java:15) Press any key to continue . . .

Three methods that might throw an exception

Class Method Throws Scanner nextDouble() InputMismatchException

Integer parseInt(String) NumberFormatException

Double parseDouble(String) NumberFormatException

Page 7: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 7

How exceptions work An exception is an object that contains information about an error

that has occurred.

When an error occurs in a method, the method throws an exception.

If an exception is thrown when you’re testing a console application, some information about the exception, including its name and stack trace, is displayed at the console.

A stack trace is a list of the methods that were called before the exception occurred. The list appears in reverse order, from the last method called to the first method called.

All exceptions are subclasses of the Exception class. The Exception class represents the most general type of exception, while the subclasses represent increasingly specific exceptions.

The class for an exception is usually stored in the same package as the class whose methods throw that type of exception.

Page 8: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 8

The syntax for the try statement try { statements } catch(ExceptionClass exceptionName) { statements }

Two ways to import the InputMismatchException class

import java.util.InputMismatchException; import.java.util.*;

Page 9: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 9

A try statement that catches an InputMismatchException double subtotal = 0.0; try { System.out.print("Enter subtotal: "); subtotal = sc.nextDouble(); } catch(InputMismatchException e) { sc.next(); // discard the incorrectly entered double System.out.println("Error! Invalid number. Try again.\n"); continue; // jump to the top of the loop }

Console output Enter subtotal: $100 Error! Invalid number. Try again. Enter subtotal:

Page 10: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 10

How to catch exceptions In a try statement (or try/catch statement):

you code any statements that may throw an exception in a try block

you can code a catch block that will handle any exceptions that may occur in the try block

When an exception occurs, any remaining statements in the try block are skipped and the statements in the catch block are executed.

Any variables or objects that are used in both the try and catch blocks must be created before the try and catch blocks so both the try and catch blocks can access them.

If you use a catch block to catch a specific type of exception, you must also import the package that contains that exception class.

Page 11: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 11

The Future Value application with exception handling import java.util.*; import java.text.NumberFormat; public class FutureValueExceptionApp { public static void main(String[] args) { System.out.println( "Welcome to the Future Value Calculator\n"); Scanner sc = new Scanner(System.in); String choice = "y"; while (choice.equalsIgnoreCase("y")) { double monthlyInvestment = 0.0; double interestRate = 0.0; int years = 0;

Page 12: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 12

The Future Value application with exception handling (continued) try { System.out.print("Enter monthly investment: "); monthlyInvestment = sc.nextDouble(); System.out.print("Enter yearly interest rate: "); interestRate = sc.nextDouble(); System.out.print("Enter number of years: "); years = sc.nextInt(); } catch(InputMismatchException e) { sc.next(); // discard the incorrectly entered number System.out.println( "Error! Invalid number. Try again.\n"); continue; // jump to the top of the loop } double monthlyInterestRate = interestRate/12/100; int months = years * 12; double futureValue = calculateFutureValue( monthlyInvestment, monthlyInterestRate, months);

Page 13: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 13

The Future Value application with exception handling (continued) NumberFormat currency = NumberFormat.getCurrencyInstance(); System.out.println("Future value: " + currency.format(futureValue) + "\n"); System.out.print("Continue? (y/n): "); choice = sc.next(); System.out.println(); } } private static double calculateFutureValue( double monthlyInvestment, double monthlyInterestRate, int months) { double futureValue = 0; for (int i = 1; i <= months; i++) futureValue = (futureValue + monthlyInvestment) * (1 + monthlyInterestRate); return futureValue; } }

Page 14: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 14

Methods of the Scanner class you can use to validate data

Method Description

hasNext() Returns true if the scanner contains another token.

hasNextInt() Returns true if the scanner contains another token that can be converted to an int value.

hasNextDouble() Returns true if the scanner contains another token that can be converted to a double value.

nextLine() Returns any remaining input on the current line as a String object and advances the scanner to the next line.

Page 15: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 15

Code that prevents an InputMismatchException double subtotal = 0.0; System.out.print("Enter subtotal: "); if (sc.hasNextDouble()) subtotal = sc.nextDouble(); else { sc.nextLine(); // discard the entire line System.out.println( "Error! Invalid number. Try again.\n"); continue; // jump to the top of the loop }

Console output Enter subtotal: $100 Error! Invalid number. Try again. Enter subtotal:

Page 16: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 16

Code that prevents a NullPointerException if (customerType != null) { if (customerType.equals("R")) discountPercent = .4; }

How to prevent exceptions from being thrown The has methods of the Scanner class let you check whether

additional data is available at the console and whether that data can be converted to a specific data type.

You can use the Scanner has methods to prevent an exception from being thrown when one of the next methods is called.

You can use the nextLine method to retrieve and discard any additional data that the user enters on a line that isn’t required.

Page 17: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 17

Code that gets a valid double value within a specified range

Scanner sc = new Scanner(System.in); double subtotal = 0.0; boolean isValid = false; while (isValid == false) { // get a valid double value System.out.print("Enter subtotal: "); if (sc.hasNextDouble()) { subtotal = sc.nextDouble(); isValid = true; } else { System.out.println( "Error! Invalid number. Try again."); } sc.nextLine(); // discard any other data entered on the line

Page 18: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 18

Code that gets a valid double value within a specified range (continued)

// check the range of the double value if (isValid == true && subtotal <= 0) { System.out.println( "Error! Number must be greater than 0."); isValid = false; } else if (isValid == true && subtotal >= 10000) { System.out.println( "Error! Number must be less than 10000."); isValid = false; } }

Page 19: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 19

How to validate an entry When a user enters data, that data usually needs to be checked to

make sure that it is valid. This is known as data validation.

When an entry is invalid, the program needs to display an error message and give the user another chance to enter valid data. This needs to be repeated until the entry is valid.

One way to code this type of validation routine is to use a while loop.

Two common types of validity checking for a numeric entry are (1) to make sure that the entry has a valid numeric format, and (2) to make sure that the entry is within a valid range (known as range checking).

Page 20: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 20

A method that gets a valid numeric format public static double getDouble(Scanner sc, String prompt) { double d = 0.0; boolean isValid = false; while (isValid == false) { System.out.print(prompt); if (sc.hasNextDouble()) { d = sc.nextDouble(); isValid = true; } else { System.out.println("Error! Invalid number. Try again."); } sc.nextLine(); // discard any other data entered on the line } return d; }

Page 21: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 21

A method that checks for a valid numeric range public static double getDoubleWithinRange(Scanner sc, String prompt, double min, double max) { double d = 0.0; boolean isValid = false; while (isValid == false) { d = getDouble(sc, prompt); // call the getDouble method if (d <= min) { System.out.println( "Error! Number must be greater than " + min + "."); } else if (d >= max) { System.out.println( "Error! Number must be less than " + max + "."); } else isValid = true; } return d; }

Page 22: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 22

Code that gets valid double values using the getDouble and getDoubleWithinRange methods Scanner sc = new Scanner(System.in); double subtotal1 = getDouble(sc, "Enter subtotal: "); double subtotal2 = getDoubleWithinRange(sc, "Enter subtotal: ", 0, 10000);

Page 23: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 23

The console for the Future Value application Welcome to the Future Value Calculator DATA ENTRY Enter monthly investment: $100 Error! Invalid decimal value. Try again. Enter monthly investment: 100 dollars Enter yearly interest rate: 120 Error! Number must be less than 30.0. Enter yearly interest rate: 12.0 Enter number of years: one Error! Invalid integer value. Try again. Enter number of years: 1 FORMATTED RESULTS Monthly investment: $100.00 Yearly interest rate: 12.0% Number of years: 1 Future value: $1,280.93 Continue? (y/n):

Page 24: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 24

The Future Value application with data validation import java.util.*; import java.text.*; public class FutureValueApp { public static void main(String[] args) { System.out.println( "Welcome to the Future Value Calculator\n"); Scanner sc = new Scanner(System.in); String choice = "y"; while (choice.equalsIgnoreCase("y")) { System.out.println("DATA ENTRY"); double monthlyInvestment = getDoubleWithinRange(sc, "Enter monthly investment: ", 0, 1000); double interestRate = getDoubleWithinRange(sc, "Enter yearly interest rate: ", 0, 30); int years = getIntWithinRange(sc, "Enter number of years: ", 0, 100);

Page 25: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 25

The Future Value application with data validation (continued) double monthlyInterestRate = interestRate/12/100; int months = years * 12; double futureValue = calculateFutureValue( monthlyInvestment, monthlyInterestRate, months); NumberFormat currency = NumberFormat.getCurrencyInstance(); NumberFormat percent = NumberFormat.getPercentInstance(); percent.setMinimumFractionDigits(1); String results = "Monthly investment:\t" + currency.format(monthlyInvestment) + "\n" + "Yearly interest rate:\t" + percent.format(interestRate/100) + "\n" + "Number of years:\t" + years + "\n" + "Future value:\t\t" + currency.format(futureValue) + "\n";

Page 26: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 26

The Future Value application with data validation (continued) System.out.println(); System.out.println("FORMATTED RESULTS"); System.out.println(results); System.out.print("Continue? (y/n): "); choice = sc.next(); sc.nextLine(); // discard any other data entered on the line System.out.println(); } } public static double getDouble(Scanner sc, String prompt) { double d = 0.0; boolean isValid = false; while (isValid == false) { System.out.print(prompt);

Page 27: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 27

The Future Value application with data validation (continued) if (sc.hasNextDouble()) { d = sc.nextDouble(); isValid = true; } else { System.out.println ("Error! Invalid decimal value. Try again."); } sc.nextLine(); // discard any other data entered on the line } return d; } public static double getDoubleWithinRange(Scanner sc, String prompt, double min, double max) { double d = 0.0; boolean isValid = false;

Page 28: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 28

The Future Value application with data validation (continued) while (isValid == false) { d = getDouble(sc, prompt); if (d <= min) { System.out.println( "Error! Number must be greater than " + min + "."); } else if (d >= max) { System.out.println( "Error! Number must be less than " + max + "."); } else isValid = true; } return d; }

Page 29: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 29

The Future Value application with data validation (continued) public static int getInt(Scanner sc, String prompt) { int i = 0; boolean isValid = false; while (isValid == false) { System.out.print(prompt); if (sc.hasNextInt()) { i = sc.nextInt(); isValid = true; } else { System.out.println ("Error! Invalid integer value. Try again."); } sc.nextLine(); // discard any other data entered on the line } return i; }

Page 30: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 30

The Future Value application with data validation (continued) public static int getIntWithinRange(Scanner sc, String prompt, int min, int max) { int i = 0; boolean isValid = false; while (isValid == false) { i = getInt(sc, prompt); if (i <= min) System.out.println( "Error! Number must be greater than " + min + "."); else if (i >= max) System.out.println( "Error! Number must be less than " + max + "."); else isValid = true; } return i; }

Page 31: Murach’s Java SE 6, C5© 2007, Mike Murach & Associates, Inc.Slide 1

Murach’s Java SE 6, C5 © 2007, Mike Murach & Associates, Inc. Slide 31

The Future Value application with data validation (continued) public static double calculateFutureValue( double monthlyInvestment, double monthlyInterestRate, int months) { double futureValue = 0; for (int i = 1; i <= months; i++) { futureValue = (futureValue + monthlyInvestment) * (1 + monthlyInterestRate); } return futureValue; } }