Raw Types

The test programs for generic class Stack in Section 18.6 instantiate Stacks with type arguments Double and Integer. It is also possible to instantiate generic class Stack without specifying a type argument, as follows:

 Stack objectStack = new Stack( 5 ); // no type argument specified

In this case, the objectStack is said to have a raw type, which means that the compiler implicitly uses type Object throughout the generic class for each type argument. Thus the preceding statement creates a Stack that can store objects of any type. This is important for backwards compatibility with prior versions of Java. For example, the data structures of the Java Collections Framework (see Chapter 19, Collections) all stored references to Objects, but are now implemented as generic types.

A raw type Stack variable can be assigned a Stack that specifies a type argument, such as a Stack< Double > object, as follows:

 Stack rawTypeStack2 = new Stack< Double >( 5 );

because type Double is a subclass of Object. This assignment is allowed because the elements in a Stack< Double > (i.e., Double objects) are certainly objectsclass Double is an indirect subclass of Object.

Similarly, a Stack variable that specifies a type argument in its declaration can be assigned a raw type Stack object, as in:

 Stack< Integer > integerStack = new Stack( 10 );

Although this assignment is permitted, it is unsafe because a Stack of raw type might store types other than Integer. In this case, the compiler issues a warning message which indicates the unsafe assignment.

The test program of Fig. 18.12 uses the notion of raw type. Line 14 instantiates generic class Stack with raw type, which indicates that rawTypeStack1 can hold objects of any type. Line 17 assigns a Stack< Double > to variable rawTypeStack2, which is declared as a Stack of raw type. Line 20 assigns a Stack of raw type to Stack< Integer > variable, which is legal but causes the compiler to issue a warning message (Fig. 18.13) indicating a potentially unsafe assignmentagain, this occurs because a Stack of raw type might store types other than Integer. Also, each of the calls to generic method testPush and testPop in lines 2225 results in a compiler warning message (Fig. 18.13). These warnings occur because variables rawTypeStack1 and rawTypeStack2 are declared as Stacks of raw type, but methods testPush and testPop each expect a second argument that is a Stack with a specific type argument. The warnings indicate that the compiler cannot guarantee that the types manipulated by the stacks are the correct types, because we did not supply a variable declared with a type argument. Methods testPush (lines 3151) and testPop (lines 5474) are the same as in Fig. 18.11.

Figure 18.12. Raw type test program.

(This item is displayed on pages 891 - 893 in the print version)

 1 // Fig. 18.12: RawTypeTest.java
 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
16 // Stack< Double > assigned to Stack of raw types variable
17 Stack rawTypeStack2 = new Stack< Double >( 5 ); 
18
19 // Stack of raw types assigned to Stack< Integer > variable
20 Stack< Integer > integerStack = new Stack( 10 ); 
21
22 testPush( "rawTypeStack1", rawTypeStack1, doubleElements );
23 testPop( "rawTypeStack1", rawTypeStack1 );
24 testPush( "rawTypeStack2", rawTypeStack2, doubleElements );
25 testPop( "rawTypeStack2", rawTypeStack2 );
26 testPush( "integerStack", integerStack, integerElements );
27 testPop( "integerStack", integerStack );
28 } // end method testStacks
29
30 // generic method pushes elements onto stack
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( "
Pushing elements onto %s
", 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
53 // generic method testPop pops elements from stack
54 public < T > void testPop( String name, Stack< T > stack )
55 {
56 // pop elements from stack
57 try
58 {
59 System.out.printf( "
Popping elements from %s
", 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
 
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)

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)
 

Figure 18.13. Warning message from the compiler.

(This item is displayed on page 894 in the print version)

RawTypeTest.java:20: warning: unchecked assignment
found : Stack
required: Stack
 Stack< Integer > integerStack = new Stack( 10 );
 ^
RawTypeTest.java:22: warning: [unchecked] unchecked method invocation:
testPush(java.lang.String,Stack,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:
testPop(java.lang.String,Stack) in RawTypeTest is applied to
(java.lang.String,Stack)
 testPop( "rawTypeStack1", rawTypeStack1 );
 ^
RawTypeTest.java:24: warning: [unchecked] unchecked method invocation:
testPush(java.lang.String,Stack,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:
testPop(java.lang.String,Stack) in RawTypeTest is applied to
(java.lang.String,Stack)
 testPop( "rawTypeStack2", rawTypeStack2 );
 ^
5 warnings
 

Figure 18.13 shows the warning messages generated by the compiler (compiled with the -Xlint:unchecked option) when the file RawTypeTest.java (Fig. 18.12) is compiled. The first warning is generated for line 20, which assigned a raw type Stack to a Stack< Integer > variablethe compiler cannot ensure that all objects in the Stack will be Integer objects. The second warning is generated for line 22. Because the second method argument is a raw type Stack variable, the compiler determines the type argument for method testPush from the Double array passed as the third argument. In this case, Double is the type argument, so the compiler expects a Stack< Double > to be passed as the second argument. The warning occurs because the compiler cannot ensure that a raw type Stack contains only Double objects. The warning at line 24 occurs for the same reason, even though the actual Stack that rawTypeStack2 references is a Stack< Double >. The compiler cannot guarantee that the variable will always refer to the same Stack object, so it must use the variable's declared type to perform all type checking. Lines 23 and 25 each generate warnings because method testPop expects as an argument a Stack for which a type argument has been specified. However, in each call to testPop, we pass a raw type Stack variable. Thus, the compiler indicates a warning because it cannot check the types used in the body of the method.

Introduction to Computers, the Internet and the World Wide Web

Introduction to Java Applications

Introduction to Classes and Objects

Control Statements: Part I

Control Statements: Part 2

Methods: A Deeper Look

Arrays

Classes and Objects: A Deeper Look

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

GUI Components: Part 1

Graphics and Java 2D™

Exception Handling

Files and Streams

Recursion

Searching and Sorting

Data Structures

Generics

Collections

Introduction to Java Applets

Multimedia: Applets and Applications

GUI Components: Part 2

Multithreading

Networking

Accessing Databases with JDBC

Servlets

JavaServer Pages (JSP)

Formatted Output

Strings, Characters and Regular Expressions

Appendix A. Operator Precedence Chart

Appendix B. ASCII Character Set

Appendix C. Keywords and Reserved Words

Appendix D. Primitive Types

Appendix E. (On CD) Number Systems

Appendix F. (On CD) Unicode®

Appendix G. Using the Java API Documentation

Appendix H. (On CD) Creating Documentation with javadoc

Appendix I. (On CD) Bit Manipulation

Appendix J. (On CD) ATM Case Study Code

Appendix K. (On CD) Labeled break and continue Statements

Appendix L. (On CD) UML 2: Additional Diagram Types

Appendix M. (On CD) Design Patterns

Appendix N. Using the Debugger

Inside Back Cover



Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net