63
Chapter 2 Additional Features of Java Programming

Chapter 2 Additional Features of Java Programming

Embed Size (px)

Citation preview

Page 1: Chapter 2 Additional Features of Java Programming

Chapter 2

Additional Features of

Java Programming

Page 2: Chapter 2 Additional Features of Java Programming

The static modifier is applied to constant identifiers (always) and method identifiers (sometimes). Static means “applying to the class as a whole, rather than to an instance of the class.”

Page 3: Chapter 2 Additional Features of Java Programming

For example, in the Integer class:

public static final int MAX_VALUE = 0x7fffffff;

= 231 - 1

There is only one copy of

MAX_VALUE instead of a separate copy for each instance of Integer. final means “Can be assigned to only once.”

Page 4: Chapter 2 Additional Features of Java Programming

To access this constant, the class name is followed by the member-designator operator (the dot) followed by the constant identifier: if (size == Integer.MAX_VALUE)

Page 5: Chapter 2 Additional Features of Java Programming

Here’s a method from java.lang.Math: public static double ceil (double a)

returns the smallest value that is greater than or equal to a and is mathematically equal to an integer. System.out.println (Math.ceil (3.17));

The output will be 4.0. There is no calling object; the argument has all that the method needs.

Page 6: Chapter 2 Additional Features of Java Programming

METHOD TESTING WITH JUnit

Page 7: Chapter 2 Additional Features of Java Programming

A method is correct if it satisfies its specification. Your confidence in the correctness of your methods is increased by testing, which can reveal the presence but not absence of errors.

Page 8: Chapter 2 Additional Features of Java Programming

JUnit is a free software package for testing a class’s

methods.

Page 9: Chapter 2 Additional Features of Java Programming

For example,

here is an indirect test of the 3-parameter constructor in the HourlyEmployee class:

Page 10: Chapter 2 Additional Features of Java Programming

@Test

public void test3()

{

hourly = new HourlyEmployee ("terry", 41, 20.00);

assertEquals (800.00, hourly.getRegularPay());

assertEquals (30.00, hourly.getOvertimePay());

assertEquals (830.00, hourly.getGrossPay());

} // method test3

Page 11: Chapter 2 Additional Features of Java Programming

import org.junit.*;import static org.junit.Assert.*;import org.junit.runner.Result;import static org.junit.runner.JUnitCore.runClasses;

import java.util.*;

public class HourlyEmployeeTest{ public static void main(String[ ] args) { Result result = runClasses (HourlyEmployeeTest.class); System.out.println ("Tests run = " + result.getRunCount() + "\nTests failed = " + result.getFailures()); } // method main  

Page 12: Chapter 2 Additional Features of Java Programming

@Test public void test1() { hourly = new HourlyEmployee ("andrew", 39, 10.00); assertEquals (390.00, hourly.getRegularPay()); assertEquals (0.00, hourly.getOvertimePay()); assertEquals (390.00, hourly.getGrossPay()); } // method test1

@Test public void test2() { hourly = new HourlyEmployee ("beth", 40, 20.00); assertEquals (800.00, hourly.getRegularPay()); assertEquals (0.00, hourly.getOvertimePay()); assertEquals (800.00, hourly.getGrossPay()); } // method test2

Page 13: Chapter 2 Additional Features of Java Programming

@Test public void test3() { hourly = new HourlyEmployee ("terry", 41, 20.00); assertEquals (800.00, hourly.getRegularPay()); assertEquals (30.00, hourly.getOvertimePay()); assertEquals (830.00, hourly.getGrossPay()); } // method test3 @Test public void test4() { hourly = new HourlyEmployee ("karen", 50, 10); assertEquals (400.00, hourly.getRegularPay()); assertEquals (150.00, hourly.getOvertimePay()); assertEquals (550.00, hourly.getGrossPay()); } // method test4} // class HourlyEmployeeTest

Page 14: Chapter 2 Additional Features of Java Programming

TESTING PRINCIPLES

Testing can reveal the presence of errors but not the absence of errors.

A method’s tests should be developed before the method

is defined.

In general, methods should be designed to facilitate testing.

Make sure that any boundary conditions are thoroughly tested.

Good testing requires great skepticism.

Page 15: Chapter 2 Additional Features of Java Programming

Exception Handling

Page 16: Chapter 2 Additional Features of Java Programming

A robust program is one that does not terminate abnormally from invalid user input.

An exception is an object created by an unusual condition, such as an attempt at invalid processing

Page 17: Chapter 2 Additional Features of Java Programming

Try to execute a block of code:

try {

… } // try

Catch the exceptions thrown (one catch block per exception type):

catch (Exception e) { … } // catch

Page 18: Chapter 2 Additional Features of Java Programming

For example, suppose we want to develop a method that scans an int and returns the words corresponding to that int. For example, if the int scanned is 537, the String returned is “five three seven”. Here is the method specification:

Page 19: Chapter 2 Additional Features of Java Programming

/** * Returns the words corresponding to the int scanned in. * * @param sc - (a reference to) a Scanner object. * * @return the words corresponding to the int scanned in * from sc, if the token scanned is an int. * Otherwise, return "java.util.InputMismatchException: " + * (the token scanned) + " is not an int.". * */ public String getNumberWords (Scanner sc)

Page 20: Chapter 2 Additional Features of Java Programming

We want to develop and run the test class for this method before we define the method. Then the tests will depend only on the method specification. But how can we run the NumberWordsTest class before we define getNumberWords? Instead of a complete definition, we will use a stub: a one-line definition that is just enough to enable the test class to be run. Of course, we expect all the tests to fail initially. Here is such a stub: public String getNumberWords (Scanner sc) { throw new UnsupportedOperationException(); } // method getNumberWords

Page 21: Chapter 2 Additional Features of Java Programming

Here is a test class for getNumberWords: import org.junit.*; import static org.junit.Assert.*; import org.junit.runner.Result; import static org.junit.runner.JUnitCore.runClasses; import java.util.*; public class NumberWordsTest { public static void main(String[ ] args) { Result result = runClasses (NumberWordsTest.class); System.out.println ("Tests run = " + result.getRunCount() + "\nTests failed = " + result.getFailures()); } // method main

Page 22: Chapter 2 Additional Features of Java Programming

public final static String EXCEPTION = “java.util.InputMismatchException"; protected NumberWords numberWords; @Before public void runBeforeEveryTest( ) { numberWords = new NumberWords(); } // method runBeforeEveryTest @Test public void test805() { assertEquals ("805 is eight zero five ", numberWords.getNumberWords (new Scanner ("805"))); } // method test805

Page 23: Chapter 2 Additional Features of Java Programming

@Test public void test0() { assertEquals ("0 is zero ", numberWords.getNumberWords (new Scanner ("0"))); } // method test0 @Test public void testMinus17() { assertEquals ("-17 is minus one seven ", numberWords.getNumberWords (new Scanner ("-17"))); } // method testMinus17

Page 24: Chapter 2 Additional Features of Java Programming

@Test public void test22z2() { assertEquals (EXCEPTION + ": 22z2 is not an int.", numberWords.getNumberWords (new Scanner ("22z2"))); } // method testtest22z2 @Test public void testx() { assertEquals (EXCEPTION + ": x is not an int.", numberWords.getNumberWords (new Scanner ("x"))); } // method testtestx } // class NumberWordsTest

Page 25: Chapter 2 Additional Features of Java Programming

And here is the rest of the file:

import java.util.*; // for the Scanner class public class NumberWords { public static void main (String[] args) { new NumberWords().run(); } // main public void run() { final String NUMBER_WORDS_MESSAGE = "\nAnswer: "; Scanner sc = new Scanner ("805 17\n22z2\n-7\n395\nx 5\n0"); while (sc.hasNext()) System.out.println (NUMBER_WORDS_MESSAGE + getNumberWords (sc)); } // method run } // class NumberWords

Page 26: Chapter 2 Additional Features of Java Programming

Now we can focus on the definition of the getNumberWords (Scanner scanner) method.

Page 27: Chapter 2 Additional Features of Java Programming

public String getNumberWords (Scanner sc) { try { String[ ] digitWords = {"zero ", "one ", "two ", "three ", "four ", "five ", "six ", "seven ", "eight ", "nine "}; int number = sc.nextInt(), saveNumber = number, digit; String sign = "", numberWords = ""; if (number < 0) { sign = "minus "; number = -number; } // if negative number

Page 28: Chapter 2 Additional Features of Java Programming

if (number == 0) numberWords = "zero "; while (number > 0) { digit = number % 10; number = number / 10; numberWords = digitWords [digit] + numberWords; } // while return Integer.toString (saveNumber) + " is " + sign + numberWords; } // try catch (InputMismatchException e) { return ??????? } // catch InputMismatchException } // method getNumberWords

Page 29: Chapter 2 Additional Features of Java Programming

What should be returned from the catch block? How about

e.toString() + “: “ + Integer.toString (saveNumber) + “ is not an int.”;

Page 30: Chapter 2 Additional Features of Java Programming

There are two problems with this: 1. The variable saveNumber is declared

in the try block, so that variable cannot be used in the catch block.

2. If sc.nextInt( ) fails because the token to be scanned is not an int, the next token to be scanned is that same, non-int token. Then the while loop in the run method would be an infinite loop once “22z2” was scanned.

Page 31: Chapter 2 Additional Features of Java Programming

We can solve both problems by scanning past that non-int token with a call to next():

catch (InputMismatchException e) { return e.toString() + “: “ + sc.next( ) + “ is not an int.”; } // catch InputMismatchException

Page 32: Chapter 2 Additional Features of Java Programming

Exercise: Complete the definition of the following method:

/** * Returns the first three letters of the name scanned. * * @param sc – (a reference to) a Scanner object. * * @returns the first three letters of the name scanned * by sc, if the name has three letters. * Otherwise, returns * “java.lang.StringIndexOutOfBoundsException: * string index out of bounds: 3” * if the name has fewer than 3 letters. * */

Page 33: Chapter 2 Additional Features of Java Programming

public String truncate (Scanner sc) { try { String name = sc.next(); return ??? } // try catch (StringIndexOutOfBoundsException e) { ??? } // catch } // method truncate

Page 34: Chapter 2 Additional Features of Java Programming

Hint: in the String class of the package java.lang,

public String substring (int start, int finish)

returns the substring from index start through index finish-1.

Page 35: Chapter 2 Additional Features of Java Programming

In the truncate method, if we want to allow for the possibility that sc may be a null reference, we would have two catch blocks: try { … } catch (StringIndexOutOfBoundsException e) { … } // catch StringIndexOutOfBoundsException catch (NullPointerException e) { … } // catch NullPointerException

Page 36: Chapter 2 Additional Features of Java Programming

In general, if you want to take the same action for several exceptions, you need only one catch block: catch (Exception e) { return e.toString(); } // catch

This will catch (and return) any exception: InputMismatchException, NoSuchElementException, StringIndexOutOfBoundsException,

NullPointerException, …

Page 37: Chapter 2 Additional Features of Java Programming

Exceptions can be explicitly thrown: if (size == Integer.MAX_VALUE) throw new ArithmeticException (“size too large”);

Page 38: Chapter 2 Additional Features of Java Programming

If an exception is not caught when it is thrown, it is “propagated” back to the calling method. For example, suppose the value scanned in the following is “1Z”.

Page 39: Chapter 2 Additional Features of Java Programming

try { System.out.println (checkPrimality (sc)); } // try catch (InputMismatchException e) { System.out.println (“oooops” + e); } // catch

public boolean checkPrimality (Scanner sc) {

int number = sc.nextInt(); …

} // method checkPrimality

Page 40: Chapter 2 Additional Features of Java Programming

Run-time exceptions, such as

InputMismatchException and

NullPointerException, are automatically propagated. Other exceptions, especially

IOException, are called checked exceptions. They can be propagated only if a throws clause appears right after the method heading.

Page 41: Chapter 2 Additional Features of Java Programming

For example, suppose we have a findMedian method in a Statistics class. try { System.out.println (findMedian (myFileName)); } // try catch (FileNotFoundException e) { System.out.println (e); } // catch FileNotFoundException

Page 42: Chapter 2 Additional Features of Java Programming

/** * Finds median of all int values in file given by filename. * @throws FileNotFoundException – if filename is not

* the name of any file. */ public int findMedian (String fileName) throws FileNotFoundException {

Scanner fileScanner = new Scanner (new File (fileName));

Cultural note: It is considered bad form for the main method to throw any exception – because then the exception will not be caught by your program.

Page 43: Chapter 2 Additional Features of Java Programming

Here is a test of the findMedian method (assume that median is a field in the test class and an instance of the class in which findMedian is defined): @Test (expected = FileNotFoundException.class) public void testBadFileName() { median.findMedian (“?&^%$@*()+_-./”); } // method testBadFileName

Page 44: Chapter 2 Additional Features of Java Programming

You need not propagate exceptions: they can be caught in the same method in which they are thrown. But sometimes a higher-level method is better equipped to handle an exception thrown in a lower-level method. For example, the higher-level method might have access to some feature – such as a Graphical User Interface (GUI) window – that is useful for handling the exception.

Page 45: Chapter 2 Additional Features of Java Programming

File Output PrintWriter printWriter = new PrintWriter

(new BufferedWriter (new FileWriter ("maze.out"))); printWriter.println (“Here is the grid:”);

Page 46: Chapter 2 Additional Features of Java Programming

The output does not immediately go to the file, but is saved in a buffer – a temporary storage area in memory. Output is transferred from the buffer to the file when the buffer is full (and fileWriter.println is called) or when fileWriter.close() is called.

Page 47: Chapter 2 Additional Features of Java Programming

The last method called by an output-file object should be

close().

Page 48: Chapter 2 Additional Features of Java Programming

File input

Scanner fileScanner = new Scanner (new File (filename));

The file name is often read in from the keyboard: Scanner sc = new Scanner (System.in); String fileName = sc.nextLine();

Page 49: Chapter 2 Additional Features of Java Programming

What can go wrong? If fileName is not the name of a file, a FileNotFoundException object will be thrown. But then another string should be read in from the keyboard and the assignment to fileScanner should be repeated.

Page 50: Chapter 2 Additional Features of Java Programming

boolean fileOK = false; while (!fileOK) { try // to create the file scanner { fileName = sc.nextLine(); fileScanner = new Scanner (new File (fileName)); while (fileScanner.hasNext()) { try // to read one int from the file { int score = fileScanner.nextInt(); … // process score } catch (InputMismatchException) { … } } // while fileScanner.hasNext() fileOK = true; } // try catch (FileNotFoundException e) { … } } // while !fileOK

Page 51: Chapter 2 Additional Features of Java Programming

The Java Virtual Machine

also known as

the Java Run-Time Environment

Page 52: Chapter 2 Additional Features of Java Programming

Java Source Code

Java Compiler

Bytecode

Java Virtual Machine

Result of Executing Program

Page 53: Chapter 2 Additional Features of Java Programming

The Java virtual machine handles all run-time aspects of your program. For example:

1. Pre-initialization of fields, just prior to a constructor call (so constant fields cannot be assigned a value after they are declared). This ensures that all fields get initialized.

Page 54: Chapter 2 Additional Features of Java Programming

2. Garbage collection: De-allocation of space for inaccessible objects

The virtual machine handles allocation

by implementing the new operator. What about de-allocation?

Page 55: Chapter 2 Additional Features of Java Programming

Suppose we have a local variable

double[] d = new double [100000];

at the end of the execution of the method, the space for the reference d is deallocated. But what about the space for the object

(100000 doubles)?

Page 56: Chapter 2 Additional Features of Java Programming

Space for that object can be deallocated provided there are no “live” references to the object. The Java virtual machine keeps track of the number of live references to an object.

Page 57: Chapter 2 Additional Features of Java Programming

Visibility modifiers: 1. public – accessible in any class

2. protected – accessible in any class within the

same package as the given class, or in any subclass of the given class

3. default – accessible in any class within the same

package as the given class

4. private – accessible only within the given class

Page 58: Chapter 2 Additional Features of Java Programming

The Object class – the superclass of all classes – has an equals method: public boolean equals (Object obj) { return this == obj; } // method equals

Page 59: Chapter 2 Additional Features of Java Programming

Because this method compares references,not objects, we should override the aboveversion for any class with an equalsmethod.

Page 60: Chapter 2 Additional Features of Java Programming

For example, let’s define an equals method for the FullTimeEmployee class: public boolean equals (Object obj) { // If obj does not reference a FullTimeEmployee // object, return false // return name equals (obj’s name) && // grossPay == obj’s grossPay; } // method equals

Page 61: Chapter 2 Additional Features of Java Programming

For example, let’s define an equals method for the FullTimeEmployee class: public boolean equals (Object obj) { // If obj does not reference a FullTimeEmployee // object, return false // return name equals (obj’s name) && // grossPay == obj’s grossPay; } // method equals Danger: In general, double values should not be tested for equality. For example, 29 * (1000.00 / 29) != 1000.00.

Page 62: Chapter 2 Additional Features of Java Programming

public boolean equals (Object obj) { if (!(obj instanceof FullTimeEmployee)) return false; FullTimeEmployee full = (FullTimeEmployee)obj; return name.equals (full.name) && MONEY.format (grossPay).equals ( MONEY.format (full.grossPay)); } // method equals

Page 63: Chapter 2 Additional Features of Java Programming

Exercise: Define an equals method in the HourlyEmployee class to override the equals method in the Object class. Two HourlyEmployee objects are equal if they have the same name, hours worked and pay rate (but pay rates should not be compared for equality).

Hint: If there is an HourlyEmployee object whose name is “Smith”, with 60 hours worked and a pay rate of $10.00 per hour, that employee should not be equal to another HourlyEmployee named “Smith” with 35 hours worked and a pay rate of $20.00 per hour. The gross pay is $700.00 in both cases.