0% found this document useful (0 votes)
5 views62 pages

JavaHTP7e 18

java
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views62 pages

JavaHTP7e 18

java
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 62

1

18

Generics

© 1992-2007 Pearson Education, Inc. All rights reserved.


2

Every man of genius sees the world at a different


angle from his fellows.
— Havelock Ellis

…our special individuality, as distinguished from our


generic humanity.
— Oliver Wendell Holmes, Sr.

Born under one law, to another bound.


— Lord Brooke

You deal in the raw material of opinion, and, if my


convictions have any validity, opinion ultimately
governs the world.
— Woodrow Wilson

© 1992-2007 Pearson Education Inc. All rights reserved.


3

OBJECTIVES
In this chapter you will learn:
▪ To create generic methods that perform identical
tasks on arguments of different types.
▪ To create a generic Stack class that can be used to
store objects of any class or interface type.
▪ To understand how to overload generic methods with
non-generic methods or with other generic methods.
▪ To understand raw types and how they help achieve
backwards compatibility.
▪ To use wildcards when precise type information about a
parameter is not required in the method body.
▪ The relationship between generics and inheritance.

© 1992-2007 Pearson Education, Inc. All rights reserved.


4

18.1 Introduction
18.2 Motivation for Generic Methods
18.3 Generic Methods: Implementation and Compile-Time
Translation
18.4 Additional Compile-Time Translation Issues:
18.5 Overloading Generic Methods
18.6 Generic Classes
18.7 Raw Types
18.8 Wildcards in Methods That Accept Type Parameters
18.9 Generics and Inheritance: Notes
18.10 Wrap-Up
18.11 Internet and Web Resources

© 1992-2007 Pearson Education, Inc. All rights reserved.


5

18.1 Introduction

• Generics
– New feature of J2SE 5.0
– Provide compile-time type safety
• Catch invalid types at compile time
– Generic methods
• A single method declaration
• A set of related methods
– Generic classes
• A single class declaration
• A set of related clases

© 1992-2007 Pearson Education, Inc. All rights reserved.


6

Software Engineering Observation 18.1

Generic methods and classes are among Java’s


most powerful capabilities for software reuse
with compile-time type safety.

© 1992-2007 Pearson Education, Inc. All rights reserved.


7

18.2 Motivation for Generic Methods

• Overloaded methods
– Perform similar operations on different types of data
– Overloaded printArray methods
• Integer array
• Double array
• Character array
– Only reference types can be used with generic methods and
classes

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.1: OverloadedMethods.java 8
2 // Using overloaded methods to print array of different types.
3
4 public class OverloadedMethods
5 {
6 // method printArray to print Integer array
7 public static void printArray( Integer[] inputArray )
8 {
9 // display array elements Method printArray accepts
10 for ( Integer element : inputArray ) an array of Integer objects
11 System.out.printf( "%s ", element );
12
13 System.out.println();
14 } // end method printArray
15
16 // method printArray to print Double array
17 public static void printArray( Double[] inputArray )
18 {
19 // display array elements
Method printArray accepts
20 for ( Double element : inputArray ) an array of Double objects
21 System.out.printf( "%s ", element );
22
23 System.out.println();
24 } // end method printArray
25

© 1992-2007 Pearson Education, Inc. All rights reserved.


26 // method printArray to print Character array 9
27 public static void printArray( Character[] inputArray )
28 {
29 // display array elements
Method printArray accepts
30 for ( Character element : inputArray ) an array of Character objects
31 System.out.printf( "%s ", element );
32
33 System.out.println();
34 } // end method printArray
35
36 public static void main( String args[] )
37 {
38 // create arrays of Integer, Double and Character
39 Integer[] integerArray = { 1, 2, 3, 4, 5, 6 };
40 Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };
41 Character[] characterArray = { 'H', 'E', 'L', 'L', 'O' };
42

© 1992-2007 Pearson Education, Inc. All rights reserved.


43 System.out.println( "Array integerArray contains:" ); 10
44 printArray( integerArray ); // pass an Integer array
45 System.out.println( "\nArray doubleArray contains:" );
At compile time, the compiler determines argument
46 printArray( doubleArray ); // pass a Double array
integerArray’s type (i.e., Integer[]), attempts
47 System.out.println( "\nArray characterArray contains:" );
to locate a method named printArray that
48 printArray( characterArray ); // pass a Character array
specifies a single Integer[] parameter (lines 7-14)
49 } // end main
50 } // end class OverloadedMethods
At compile time, the compiler determines argument
Array integerArray contains:
doubleArray’s type (i.e., Double[]), attempts to
1 2 3 4 5 6
locate a method named printArray that specifies
Array doubleArray contains: a single Double[] parameter (lines 17-24)
1.1 2.2 3.3 4.4 5.5 6.6 7.7

Array characterArray contains: At compile time, the compiler determines argument


H E L L O characterArray’s type (i.e., Character[]),
attempts to locate a method named printArray that
specifies a single Character[] parameter (lines 27-
34)

© 1992-2007 Pearson Education, Inc. All rights reserved.


11

18.2 Motivation for Generic Methods


(Cont.)
• Study each printArray method
– Array element type appears in two location
• Method header
• for statement header
• Combine three printArray methods into one
– Replace the element types with a generic name E
– Declare one printArray method
• Display the string representation of the elements of any array

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 public static void printArray( E[] inputArray ) 12
2 {
3 // display array elements Replace the element type with
4 for ( E element : inputArray ) a single generic type E
5 System.out.printf( "%s ", element );
Replace the element type with
6
a single generic type E
7 System.out.println();
8 } // end method printArray

Fig. 18.2 | printArray method in which actual type names are replaced by
convention with the generic name E.

© 1992-2007 Pearson Education, Inc. All rights reserved.


13

18.3 Generic Methods: Implementation


and Compile-Time Translation
• Reimplement Fig. 18.1 using a generic method
– Method calls are identical
– Outputs are identical
• Generic method declaration
– Type parameter section
• Delimited by angle brackets ( < and > )
• Precede the method’s return type
• Contain one or more type parameters
– Also called formal type paramters

© 1992-2007 Pearson Education, Inc. All rights reserved.


14

18.3 Generic Methods: Implementation


and Compile-Time Translation
• Type parameter
– Also known as type variable
– An identifier that specifies a generic type name
– Used to declare return type, parameter types and local
variable types
– Act as placeholders for the types of the argument passed to
the generic method
• Actual type arguments
– Can be declared only once but can appear more than once
public static < E > void printTwoArrays(
E[] array1, E[] array2 )

© 1992-2007 Pearson Education, Inc. All rights reserved.


15

Common Programming Error 18.1

When declaring a generic method, failing to place


a type parameter section before the return type of
a method is a syntax error—the compiler will not
understand the type parameter name when it is
encountered in the method.

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.3: GenericMethodTest.java 16
2 // Using generic methods to print array of different types.
3
4 public class GenericMethodTest
5 { Use the type parameter to declare
6 // generic method printArray method printArray’s parameter type
7 public static < E > void printArray( E[] inputArray )
8 {
9 // display array elements Type parameter section delimited
10 ) angle brackets (< and > )
for ( E element : inputArray by
11 System.out.printf( "%s ", element );
12 Use the type parameter to declare method
13 System.out.println(); printArray’s local variable type
14 } // end method printArray
15
16 public static void main( String args[] )
17 {
18 // create arrays of Integer, Double and Character
19 Integer[] intArray = { 1, 2, 3, 4, 5 };
20 Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };
21 Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
22

© 1992-2007 Pearson Education, Inc. All rights reserved.


23 System.out.println( "Array integerArray contains:" ); 17
24 printArray( integerArray ); // pass an Integer array
25 System.out.println( "\nArray doubleArray contains:" );
26
Invoke generic method printArray
printArray( doubleArray ); // pass a Double array
27 System.out.println( "\nArray characterArray an Integer
withcontains:" ); array
28 printArray( characterArray ); // pass a Character array
29 } // end main
Invoke generic method printArray
30 } // end class GenericMethodTest
with a Double array
Array integerArray contains:
1 2 3 4 5 6

Array doubleArray contains:


Invoke generic method printArray
1.1 2.2 3.3 4.4 5.5 6.6 7.7 with a Character array
Array characterArray contains:
H E L L O

© 1992-2007 Pearson Education, Inc. All rights reserved.


18

Good Programming Practice 18.1

It is recommended that type parameters be


specified as individual capital letters. Typically,
a type parameter that represents the type of an
element in an array (or other collection) is
named E for “element.”

© 1992-2007 Pearson Education, Inc. All rights reserved.


19

Common Programming Error 18.2

If the compiler cannot match a method call to


a non-generic or a generic method declaration,
a compilation error occurs.

© 1992-2007 Pearson Education, Inc. All rights reserved.


20

Common Programming Error 18.3

If the compiler does not find a method declaration


that matches a method call exactly, but does find
two or more generic methods that can satisfy the
method call, a compilation error occurs.

© 1992-2007 Pearson Education, Inc. All rights reserved.


21

18.3 Generic Methods: Implementation


and Compile-Time Translation (Cont.)
• Compile-time translation
– Erasure
• Remove type parameter section
• Replace type parameters with actual types
• Default type is Object

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 public static void printArray( Object[] inputArray ) 22
2 {
3 // display array elements Remove type parameter section and replace
4 for ( Object element : inputArray ) type parameter with actual type Object
5 System.out.printf( "%s ", element );
6 Replace type parameter with
7 System.out.println(); actual type Object
8 } // end method printArray

Fig. 18.4 | Generic method printArray after erasure is performed by the


compiler.

© 1992-2007 Pearson Education, Inc. All rights reserved.


18.4 Additional Compile-Time Translation 23

Issues: Methods That Use a Type Parameter as


the Return Type
• Application of Fig. 18.5
– Generic method
– Use Type parameters in the return type and parameter list
• Generic interface
– Specify, with a single interface declaration, a set of related types
– E.g., Comparable< T >
• Method integer1.compareTo( integer2 )
– Compare two objects of the same class
– Return 0 if two objects are equal
– Return -1 if integer1 is less than integer2
– Return 1 if integer1 is greater than integer2

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.5: MaximumTest.java 24
2 // Generic method maximum returns the largest of three objects.
3
4 public class MaximumTest
5 {
6 // determines the largest of three Comparable objects
7 public static < T extends Comparable< T > > T maximum( T x, T y, T z )
8 {
9 Type
T max = x; // assume x is initially the largest parameter
Typesection
parameter
specifies
is usedthat
in the
only
10 objectmax
Assign x to local variable of classes
returnthat
typeimplement maximum
of methodinterface
11 if ( y.compareTo( max ) > 0 ) Comparable can be used with this method
12 max = y; // y is the largest so far
Invokes method compareTo method
13
Comparable to compare y and max
14 if ( z.compareTo( max ) > 0 )
15 max = z; // z is the largest Invokes method compareTo method
16
Comparable to compare z and max
17 return max; // returns the largest object
18 } // end method maximum
19

© 1992-2007 Pearson Education, Inc. All rights reserved.


20 public static void main( String args[] ) 25
21 {
22 System.out.printf( "Maximum of %d, %d and %d is %d\n\n", 3, 4, 5,
23 maximum( 3, 4, 5 ) );
Invoke generic method
24 System.out.printf( "Maximum of %.1f, %.1f and %.1f is %.1f\n\n",
maximum with three integers
25 6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
26 System.out.printf( "Maximum of %s, %s and %s is %s\n", Invoke
"pear",generic
method
27 "apple", "orange", maximum( "pear", "apple", maximum
"orange" ) ); with three doubles
28 } // end main
29 } // end class MaximumTest Invoke generic method
maximum with three strings

Maximum of 3, 4 and 5 is 5

Maximum of 6.6, 8.8 and 7.7 is 8.8

Maximum of pear, apple and orange is pear

© 1992-2007 Pearson Education, Inc. All rights reserved.


18.4 Additional Compile-Time Translation 26

Issues: Methods That Use a Type Parameter as


the Return Type (Cont.)
• Upper bound of type parameter
– Default is Object
– Always use keyword extends
• E.g., T extends Comparable< T >
– When compiler translates generic method to Java bytecode
• Replaces type parameter with its upper bound
• Insert explicit cast operation
e.g., line 23 of Fig. 18.5 I preceded by an Integer cast
(Integer) maximum( 3, 4, 5 )

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 public static Comparable maximum(Comparable x, Comparable y, Comparable z) 27
2 {
3
Erasure replaces type parameter T
Comparable max = x; // assume x is initially the largest
4 with its upper bound Comparable
5 if ( y.compareTo( max ) > 0 )
6 max = y; // y is the largest so far
7 Erasure replaces type parameter T
8 if ( z.compareTo( max ) > ) its upper bound Comparable
0with
9 max = z; // z is the largest
10
11 return max; // returns the largest object
12 } // end method maximum

© 1992-2007 Pearson Education, Inc. All rights reserved.


28

18.5 Overloading Generic Method

• Generic method may be overloaded


– By another generic method
• Same method name but different method parameters
– By non-generic methods
• Same method name and number of parameters
• When compiler encounters a method call
– Search for most precise matching method first
• Exact method name and argument types
– Then search for inexact but applicable matching method

© 1992-2007 Pearson Education, Inc. All rights reserved.


29

18.6 Generic Classes

• Generic classes
– Use a simple, concise notation to indicate the actual type(s)
– At compilation time, Java compiler
• ensures the type safety
• uses the erasure technique to enable client code to interact
with the generic class
• Parameterized classes
– Also called parameterized types
– E.g., Stack< Double >

© 1992-2007 Pearson Education, Inc. All rights reserved.


30

18.6 Generic Classes (Cont.)

• Generic class declaration


– Looks like a non-generic class declaration
– Except class name is followed by a type parameter section
• The –Xlint:unchecked option
– Compiler cannot 100% ensure type safety

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.7: Stack.java 31
2 // Generic class Stack.
3
4 public class Stack< E >
5 {
6
Generic class declaration, class name is
private final int size; // number of elements in the stack
7 private int top; // location of thefollowed by a type parameter
top element section
8 private E[] elements; // array that stores stack elements
9
Declare elements as an array
10 // no-argument constructor creates a stack of the default size
11 public Stack()
that stores objects of type E
12 {
13 this( 10 ); // default stack size
14 } // end no-argument Stack constructor
15
16 // constructor creates a stack of the specified number of elements
17 public Stack( int s )
18 {
19 size = s > 0 ? s : 10; // set size of Stack
20 top = -1; // Stack initially empty
21
22 elements = ( E[] ) new Object[ size ]; // create array
23 } // end Stack constructor Create an array of type E. The generic
24 mechanism does not allow type parameter
in array-creation expressions because the
type parameter is not available at runtime

© 1992-2007 Pearson Education, Inc. All rights reserved.


25 // push element onto stack; if successful, return true; 32
26 // otherwise, throw FullStackException
27 public void push( E pushValue )
28 {
Method push pushes
29 if ( top == size - 1 ) // if stack is full
30 throw new FullStackException(
element of type E onto stack
String.format(
31 "Stack is full, cannot push %s", pushValue ) );
32
33 elements[ ++top ] = pushValue; // place pushValue on Stack
34 } // end method push
35
36 // return the top element if not empty; else throw EmptyStackException
37 public E pop()
38 { Method pop returns the top
39 if ( top == -1 ) // if element,
stack is which
empty is of type E
40 throw new EmptyStackException( "Stack is empty, cannot pop" );
41
42 return elements[ top-- ]; // remove and return top element of Stack
43 } // end method pop
44 } // end class Stack< E >

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.8: FullStackException.java 33
2 // Indicates a stack is full.
3 public class FullStackException extends RuntimeException
4 {
5 // no-argument constructor
6 public FullStackException()
7 {
8 this( "Stack is full" );
9 } // end no-argument FullStackException constructor
10
11 // one-argument constructor
12 public FullStackException( String exception )
13 {
14 super( exception );
15 } // end one-argument FullStackException constructor
16 } // end class FullStackException

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.9: EmptyStackException.java 34
2 // Indicates a stack is full.
3 public class EmptyStackException extends RuntimeException
4 {
5 // no-argument constructor
6 public EmptyStackException()
7 {
8 this( "Stack is empty" );
9 } // end no-argument EmptyStackException constructor
10
11 // one-argument constructor
12 public EmptyStackException( String exception )
13 {
14 super( exception );
15 } // end one-argument EmptyStackException constructor
16 } // end class EmptyStackException

© 1992-2007 Pearson Education, Inc. All rights reserved.


35

18.6 Generic Classes (Cont.)

• Generic class at compilation time


– Compiler performs erasure on class’s type parameters
– Compiler replaces type parameters with their upper bound
• Generic class test program at compilation time
– Compiler performs type checking
– Compiler inserts cast operations as necessary

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.10: StackTest.java 36
2 // Stack generic class test program.
3
4 public class StackTest
5 {
6 private double[] doubleElements = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
7 private int[] integerElements = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
8
9 private Stack< Double > doubleStack; // stack stores Double objects
10 private Stack< Integer > integerStack; // stack stores Integer objects
11
Generic class Stack’s type
12 // test Stack objects argument is Double
13 public void testStacks()
Generic class Stack’s type
14 {
15 doubleStack = new Stack< Double >( 5 ); //argument
Stack of is Integer
Doubles
16 integerStack = new Stack< Integer >( 10 ); // Stack of Integers
17 Instantiate object doubleStack of
18 testPushDouble(); // push double onto doubleStack size 5 and ingeterStack of size 10
19 testPopDouble(); // pop from doubleStack
20 testPushInteger(); // push int onto intStack
21 testPopInteger(); // pop from intStack
22 } // end method testStacks
23

© 1992-2007 Pearson Education, Inc. All rights reserved.


24 // test push method with double stack 37
25 public void testPushDouble()
26 {
27 // push elements onto stack
28 try
29 {
30 System.out.println( "\nPushing elements onto doubleStack" );
31
32 // push elements to Stack
33 for ( double element : doubleElements )
34 {
35 System.out.printf( "%.1f ", element );
36 doubleStack.push( element ); // push onto doubleStack
37 } // end for
Invoke Stack’s method push to place
38 } // end try
39 catch ( FullStackException fullStackException ) a double value onto doubleStack
40 {
41 System.err.println();
42 fullStackException.printStackTrace();
43 } // end catch FullStackException
44 } // end method testPushDouble
45

© 1992-2007 Pearson Education, Inc. All rights reserved.


46 // test pop method with double stack 38
47 public void testPopDouble()
48 {
49 // pop elements from stack
50 try
51 {
52 System.out.println( "\nPopping elements from doubleStack" );
53 double popValue; // store element removed from stack
54
55 // remove all elements from Stack
56 while ( true )
57 {
58 popValue = doubleStack.pop(); // pop from doubleStack
59 System.out.printf( "%.1f ", popValue );
60 } // end while
Auto-unboxing occurs when the value
61 } // end try
returned by pop (Double) is assigned
62 catch( EmptyStackException emptyStackException ) to a double primitive variable
63 {
64 System.err.println();
65 emptyStackException.printStackTrace();
66 } // end catch EmptyStackException
67 } // end method testPopDouble
68

© 1992-2007 Pearson Education, Inc. All rights reserved.


69 // test push method with integer stack 39
70 public void testPushInteger()
71 {
72 // push elements to stack
73 try
74 {
75 System.out.println( "\nPushing elements onto intStack" );
76
77 // push elements to Stack
78 for ( int element : integerElements )
79 {
80 System.out.printf( "%d ", element );
81 integerStack.push( element ); // push onto integerStack
82 } // end for Invoke Stack’s method push to place
83 } // end try
an int value onto integerStack
84 catch ( FullStackException fullStackException )
85 {
86 System.err.println();
87 fullStackException.printStackTrace();
88 } // end catch FullStackException
89 } // end method testPushInteger
90

© 1992-2007 Pearson Education, Inc. All rights reserved.


91 // test pop method with integer stack 40
92 public void testPopInteger()
93 {
94 // pop elements from stack
95 try
96 {
97 System.out.println( "\nPopping elements from intStack" );
98 int popValue; // store element removed from stack
99
100 // remove all elements from Stack
101 while ( true )
102 {
103 popValue = integerStack.pop(); // pop from intStack
104 System.out.printf( "%d ", popValue ); Auto-unboxing occurs when the value
105 } // end while
returned by pop (Integer) is assigned
106 } // end try
to an int primitive variable
107 catch( EmptyStackException emptyStackException )
108 {
109 System.err.println();
110 emptyStackException.printStackTrace();
111 } // end catch EmptyStackException
112 } // end method testPopInteger
113
114 public static void main( String args[] )
115 {
116 StackTest application = new StackTest();
117 application.testStacks();
118 } // end main
119 } // end class StackTest

© 1992-2007 Pearson Education, Inc. All rights reserved.


41
Pushing elements onto doubleStack
1.1 2.2 3.3 4.4 5.5 6.6
FullStackException: Stack is full, cannot push 6.6
at Stack.push(Stack.java:30)
at StackTest.testPushDouble(StackTest.java:36)
at StackTest.testStacks(StackTest.java:18)
at StackTest.main(StackTest.java:117)
Popping elements from doubleStack
5.5 4.4 3.3 2.2 1.1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at StackTest.testPopDouble(StackTest.java:58)
at StackTest.testStacks(StackTest.java:19)
at StackTest.main(StackTest.java:117)

Pushing elements onto integerStack


1 2 3 4 5 6 7 8 9 10 11
FullStackException: Stack is full, cannot push 11
at Stack.push(Stack.java:30)
at StackTest.testPushInteger(StackTest.java:81)
at StackTest.testStacks(StackTest.java:20)
at StackTest.main(StackTest.java:117)
Popping elements from integerStack
10 9 8 7 6 5 4 3 2 1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at StackTest.testPopInteger(StackTest.java:103)
at StackTest.testStacks(StackTest.java:21)
at StackTest.main(StackTest.java:117)

© 1992-2007 Pearson Education, Inc. All rights reserved.


42

18.6 Generic Classes (Cont.)


• Creating generic methods to test class Stack< E >
– Method testPush
• Perform same tasks as testPushDouble and
testPushInteger
– Method testPop
• Perform same tasks as testPopDouble and
testPopInteger

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.11: StackTest2.java 43
2 // Stack generic class test program.
3
4 public class StackTest2
5 {
6 private Double[] doubleElements = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
7 private Integer[] integerElements =
8 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
9
10 private Stack< Double > doubleStack; // stack stores Double objects
11 private Stack< Integer > integerStack; // stack stores Integer objects
12
13 // test Stack objects
14 public void testStacks()
15 {
16 doubleStack = new Stack< Double >( 5 ); // Stack of Doubles
17 integerStack = new Stack< Integer >( 10 ); // Stack of Integers
18
19 testPush( "doubleStack", doubleStack, doubleElements );
20 testPop( "doubleStack", doubleStack );
21 testPush( "integerStack", integerStack, integerElements ); generic methods testPush and
Invoke
22 testPop( "integerStack", integerStack ); testPop to push elements onto stack
23 } // end method testStacks
and pop elements from stack
24

© 1992-2007 Pearson Education, Inc. All rights reserved.


25 // generic method testPush pushes elements onto a Stack 44
26 public < T > void testPush( String name, Stack< T > stack,
27 T[] elements )
28 { Generic method testPush replaces
29 // push elements onto stack testPushDouble and testPushInteger
30 try
31 {
32 System.out.printf( "\nPushing elements onto %s\n", name );
33
34 // push elements onto Stack
35 for ( T element : elements )
36 { Replace element type Double/Integer
37 System.out.printf( "%s ", element );
with type parameter T
38 stack.push( element ); // push element onto stack
39 }
40 } // end try
41 catch ( FullStackException fullStackException )
42 {
43 System.out.println();
44 fullStackException.printStackTrace();
45 } // end catch FullStackException
46 } // end method testPush
47

© 1992-2007 Pearson Education, Inc. All rights reserved.


48 // generic method testPop pops elements from a Stack 45
49 public < T > void testPop( String name, Stack< T > stack )
50 {
51 // pop elements from stack Generic method testPop replaces
52 try testPopDouble and testPopInteger
53 {
54 System.out.printf( "\nPopping elements from %s\n", name );
55 T popValue; // store element removed from stack
56
Replace element type Double/Integer
57 // remove elements from Stack
58 while ( true )
with type parameter T
59 {
60 popValue = stack.pop(); // pop from stack
61 System.out.printf( "%s ", popValue );
62 } // end while
63 } // end try
64 catch( EmptyStackException emptyStackException )
65 {
66 System.out.println();
67 emptyStackException.printStackTrace();
68 } // end catch EmptyStackException
69 } // end method testPop
70
71 public static void main( String args[] )
72 {
73 StackTest2 application = new StackTest2();
74 application.testStacks();
75 } // end main
76 } // end class StackTest2

© 1992-2007 Pearson Education, Inc. All rights reserved.


46
Pushing elements onto doubleStack
1.1 2.2 3.3 4.4 5.5 6.6
FullStackException: Stack is full, cannot push 6.6
at Stack.push(Stack.java:30)
at StackTest2.testPush(StackTest2.java:38)
at StackTest2.testStacks(StackTest2.java:19)
at StackTest2.main(StackTest2.java:74)

Popping elements from doubleStack


5.5 4.4 3.3 2.2 1.1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at StackTest2.testPop(StackTest2.java:60)
at StackTest2.testStacks(StackTest2.java:20)
at StackTest2.main(StackTest2.java:74)

Pushing elements onto integerStack


1 2 3 4 5 6 7 8 9 10 11
FullStackException: Stack is full, cannot push 11
at Stack.push(Stack.java:30)
at StackTest2.testPush(StackTest2.java:38)
at StackTest2.testStacks(StackTest2.java:21)
at StackTest2.main(StackTest2.java:74)

Popping elements from integerStack


10 9 8 7 6 5 4 3 2 1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at StackTest2.testPop(StackTest2.java:60)
at StackTest2.testStacks(StackTest2.java:22)
at StackTest2.main(StackTest2.java:74)

© 1992-2007 Pearson Education, Inc. All rights reserved.


47

18.7 Raw Types


• Raw type
– Enables to instantiate generic class without specifying a
type argument
e.g., Stack objectStack = new Stack( 5 );
objectStack is said to have a raw type
– Important for backwards compatibility with prior versions
– A raw type Stack variable can be assigned a Stack that
specifies a type argument
– A Stack variable that specifies a type argument can be
assigned a raw type Stack
• Permitted but unsafe
• Use the –Xlint:unchecked option to compile

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.12: RawTypeTest.java 48
2 // Raw type test program.
3
4 public class RawTypeTest
5 {
6 private Double[] doubleElements = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
7 private Integer[] integerElements =
8 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
9
10 // method to test Stacks with raw types
11 public void testStacks()
12 {
13 // Stack of raw types assigned to Stack of raw types variable
14 Stack rawTypeStack1 = new Stack( 5 );
15 Instantiate generic class
16 // Stack< Double > assigned to Stack of raw types variable
Stack with raw type
17 Stack rawTypeStack2 = new Stack< Double >( 5 );
18 Assign a Stack< Double >
19 // Stack of raw types assigned to Stack< Integer > variable
to variable rawTypeStack2
20 Stack< Integer > integerStack = new Stack( 10 );
21
Assign a Stack of raw type
22 testPush( "rawTypeStack1", rawTypeStack1, doubleElements );
23 testPop( "rawTypeStack1", rawTypeStack1 ); to Stack< Integer >.
24 testPush( "rawTypeStack2", rawTypeStack2, doubleElements ); Legal but unsafe
25 testPop( "rawTypeStack2", rawTypeStack2 );
26 testPush( "integerStack", integerStack, integerElements );
27 testPop( "integerStack", integerStack );
28 } // end method testStacks
29

© 1992-2007 Pearson Education, Inc. All rights reserved.


30 // generic method pushes elements onto stack 49
31 public < T > void testPush( String name, Stack< T > stack,
32 T[] elements )
33 {
34 // push elements onto stack
35 try
36 {
37 System.out.printf( "\nPushing elements onto %s\n", name );
38
39 // push elements onto Stack
40 for ( T element : elements )
41 {
42 System.out.printf( "%s ", element );
43 stack.push( element ); // push element onto stack
44 } // end for
45 } // end try
46 catch ( FullStackException fullStackException )
47 {
48 System.out.println();
49 fullStackException.printStackTrace();
50 } // end catch FullStackException
51 } // end method testPush
52

© 1992-2007 Pearson Education, Inc. All rights reserved.


53 // generic method testPop pops elements from stack 50
54 public < T > void testPop( String name, Stack< T > stack )
55 {
56 // pop elements from stack
57 try
58 {
59 System.out.printf( "\nPopping elements from %s\n", name );
60 T popValue; // store element removed from stack
61
62 // remove elements from Stack
63 while ( true )
64 {
65 popValue = stack.pop(); // pop from stack
66 System.out.printf( "%s ", popValue );
67 } // end while
68 } // end try
69 catch( EmptyStackException emptyStackException )
70 {
71 System.out.println();
72 emptyStackException.printStackTrace();
73 } // end catch EmptyStackException
74 } // end method testPop
75
76 public static void main( String args[] )
77 {
78 RawTypeTest application = new RawTypeTest();
79 application.testStacks();
80 } // end main
81 } // end class RawTypeTest

© 1992-2007 Pearson Education, Inc. All rights reserved.


51
Pushing elements onto rawTypeStack1
1.1 2.2 3.3 4.4 5.5 6.6
FullStackException: Stack is full, cannot push 6.6
at Stack.push(Stack.java:30)
at RawTypeTest.testPush(RawTypeTest.java:43)
at RawTypeTest.testStacks(RawTypeTest.java:22)
at RawTypeTest.main(RawTypeTest.java:79)

Popping elements from rawTypeStack1


5.5 4.4 3.3 2.2 1.1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at RawTypeTest.testPop(RawTypeTest.java:65)
at RawTypeTest.testStacks(RawTypeTest.java:23)
at RawTypeTest.main(RawTypeTest.java:79)

Pushing elements onto rawTypeStack2


1.1 2.2 3.3 4.4 5.5 6.6
FullStackException: Stack is full, cannot push 6.6
at Stack.push(Stack.java:30)
at RawTypeTest.testPush(RawTypeTest.java:43)
at RawTypeTest.testStacks(RawTypeTest.java:24)
at RawTypeTest.main(RawTypeTest.java:79)

© 1992-2007 Pearson Education, Inc. All rights reserved.


52
Popping elements from rawTypeStack2
5.5 4.4 3.3 2.2 1.1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at RawTypeTest.testPop(RawTypeTest.java:65)
at RawTypeTest.testStacks(RawTypeTest.java:25)
at RawTypeTest.main(RawTypeTest.java:79)

Pushing elements onto integerStack


1 2 3 4 5 6 7 8 9 10 11
FullStackException: Stack is full, cannot push 11
at Stack.push(Stack.java:30)
at RawTypeTest.testPush(RawTypeTest.java:43)
at RawTypeTest.testStacks(RawTypeTest.java:26)
at RawTypeTest.main(RawTypeTest.java:79)

Popping elements from integerStack


10 9 8 7 6 5 4 3 2 1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at RawTypeTest.testPop(RawTypeTest.java:65)
at RawTypeTest.testStacks(RawTypeTest.java:27)
at RawTypeTest.main(RawTypeTest.java:79)

© 1992-2007 Pearson Education, Inc. All rights reserved.


53
RawTypeTest.java:20: warning: unchecked assignment
found : Stack
required: Stack<java.lang.Integer>
Stack< Integer > integerStack = new Stack( 10 );
^
RawTypeTest.java:22: warning: [unchecked] unchecked method invocation:
<T>testPush(java.lang.String,Stack<T>,T[]) in RawTypeTest is applied to
(java.lang.String,Stack,java.lang.Double[])
testPush( "rawTypeStack1", rawTypeStack1, doubleElements );
^
RawTypeTest.java:23: warning: [unchecked] unchecked method invocation:
<T>testPop(java.lang.String,Stack<T>) in RawTypeTest is applied to
(java.lang.String,Stack)
testPop( "rawTypeStack1", rawTypeStack1 );
^
RawTypeTest.java:24: warning: [unchecked] unchecked method invocation:
<T>testPush(java.lang.String,Stack<T>,T[]) in RawTypeTest is applied to
(java.lang.String,Stack,java.lang.Double[])
testPush( "rawTypeStack2", rawTypeStack2, doubleElements );
^
RawTypeTest.java:25: warning: [unchecked] unchecked method invocation:
<T>testPop(java.lang.String,Stack<T>) in RawTypeTest is applied to
(java.lang.String,Stack)
testPop( "rawTypeStack2", rawTypeStack2 );
^
5 warnings

Fig. 18.13 | Warning message from the compiler.

© 1992-2007 Pearson Education, Inc. All rights reserved.


54

18.8 Wildcards in Methods That Accept


Type Parameters
• Data structure ArrayList
– Dynamically resizable, array-like data structure
– Method add
– Method toString
• Motivation for using wildcards
– Implement a generic method sum
• Total the numbers in a collection
• Receive a parameter of type ArrayList< Number >
• Use method doubleValue of class Number to obtain the
Number’s underlying primitive value as a double value

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.14: TotalNumbers.java 55
2 // Summing the elements of an ArrayList.
3 import java.util.ArrayList;
4
5 public class TotalNumbers
6 {
7 public static void main( String args[] )
8 {
9 Declare
// create, initialize and output ArrayList of Numbers and initialize
containing
10 // both Integers and Doubles, then display total of the numbers
array elements
11 Number[] numbers = { 1, 2.4, 3, 4.1 }; // Integers and Doubles
12 ArrayList< Number > numberList = new ArrayList< Number >();
13
14 for ( Number element : numbers ) Declare and initialize numberList,
15 numberList.add( element ); // place each numberwhich stores Number objects
in numberList
16 Add elements in numbers array
17 System.out.printf( "numberList contains: %s\n", numberList );
to ArrayList numberList
18 System.out.printf( "Total of the elements in numberList: %.1f\n",
19 sum( numberList ) );
20 } // end main Invoke method sum to calculate the total
21
of the elements stored in numberList

© 1992-2007 Pearson Education, Inc. All rights reserved.


22 // calculate total of ArrayList elements 56
23 public static double sum( ArrayList< Number > list )
24 {
Method sum accepts an ArrayList
25 double total = 0; // initialize total
that stores Number objects
26
27 // calculate sum
28 for ( Number element : list )
29 total += element.doubleValue();
30 Use method doubleValue of class
31 return total; Number to obtain the Number’s underlying
32 } // end method sum primitive value as a double value
33 } // end class TotalNumbers

numberList contains: [1, 2.4, 3, 4.1]


Total of the elements in numberList: 10.5

© 1992-2007 Pearson Education, Inc. All rights reserved.


57

18.8 Wildcards in Methods That Accept


Type Parameters (Cont.)
• Implementing method sum with a wildcard type
argument in its parameter
– Number is the superclass of Integer
– ArrayList< Number > is not a supertype of
ArrayList< Integer >
– Cannot pass ArrayList< Integer > to method sum
– Use wildcard to create a more flexible version of sum
• ArrayList< ? extends Number >
• ? Represents an “unknown type”
• Unknown type argument must be either Number or a
subclass of Number
• Cannot use wildcard as a type name through method body

© 1992-2007 Pearson Education, Inc. All rights reserved.


1 // Fig. 18.15: WildcardTest.java 58
2 // Wildcard test program.
3 import java.util.ArrayList;
4
5 public class WildcardTest
6 {
7 public static void main( String args[] )
8 {
9 // create, initialize and output ArrayList of Integers, then
10 // display total of the elements
11 Integer[] integers = { 1, 2, 3, 4, 5 };
12 ArrayList< Integer > integerList = new ArrayList< Integer >();
13
14 // insert elements in integerList
Declare and create ArrayList
15 for ( Integer element : integers ) integerList to hold Integers
16 integerList.add( element );
17
18 System.out.printf( "integerList contains: %s\n", integerList );
19 System.out.printf( "Total of the elements in integerList: %.0f\n\n",
20 sum( integerList ) );
21 Invoke method sum to calculate the total
22 // create, initialize and output ArrayList of Doubles, then
of the elements stored in integerList
23 // display total of the elements
24 Double[] doubles = { 1.1, 3.3, 5.5 };
25 ArrayList< Double > doubleList = new ArrayList< Double >();
26
27 // insert elements in doubleList
Declare and create ArrayList
28 for ( Double element : doubles ) doubleList to hold Doubles
29 doubleList.add( element );
30

© 1992-2007 Pearson Education, Inc. All rights reserved.


31 System.out.printf( "doubleList contains: %s\n", doubleList ); 59
32 System.out.printf( "Total of the elements in doubleList: %.1f\n\n",
33 sum( doubleList ) );
34 Invoke method sum to calculate the total
35 // create, initialize and output ArrayList of Numbers containing
of the elements stored in doubleList
36 // both Integers and Doubles, then display total of the elements
37 Number[] numbers = { 1, 2.4, 3, 4.1 }; // Integers and Doubles
38 ArrayList< Number > numberList = new ArrayList< Number >();
39
40 // insert elements in numberList Declare and create ArrayList
41 for ( Number element : numbers ) integerList to hold Numberss
42 numberList.add( element );
43
44 System.out.printf( "numberList contains: %s\n", numberList );
45 System.out.printf( "Total of the elements in numberList: %.1f\n",
46 sum( numberList ) );
47 } // end main
Invoke method sum to calculate the total
48
of the elements stored in numberList
49 // calculate total of stack elements
50 public static double sum( ArrayList< ? extends Number > list )
51 {
52 double total = 0; // initialize total The ArrayList argument’s element types
53 are not directly known by the method, they
are known to be at least of type Number

© 1992-2007 Pearson Education, Inc. All rights reserved.


54 // calculate sum 60
55 for ( Number element : list )
56 total += element.doubleValue();
57
58 return total;
59 } // end method sum
60 } // end class WildcardTest

integerList contains: [1, 2, 3, 4, 5]


Total of the elements in integerList: 15

doubleList contains: [1.1, 3.3, 5.5]


Total of the elements in doubleList: 9.9

numberList contains: [1, 2.4, 3, 4.1]


Total of the elements in numberList: 10.5

© 1992-2007 Pearson Education, Inc. All rights reserved.


61

Common Programming Error 18.4

Using a wildcard in a method’s type parameter


section or using a wildcard as an explicit type of a
variable in the method body is a syntax error.

© 1992-2007 Pearson Education, Inc. All rights reserved.


62

18.9 Generics and Inheritance: Notes

• Inheritance in generics
– Generic class can be derived from non-generic class
e.g., class Object is superclass of every generic class
– Generic class can be derived from another generic class
e.g., Stack is a subclass of Vector
– Non-generic class can be derived from generic class
e.g., Properties is a subclass of Hashtable
– Generic method in subclass can override generic method in
superclass
• If both methods have the same signature

© 1992-2007 Pearson Education, Inc. All rights reserved.

You might also like