AhmadLang / Java, How To Program, 2004
.pdf
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 |
|
|
|
|
A wildcard type argument is denoted by a question mark ( ? ). A question mark by itself represents an "unknown type." In this case, the wildcard extends class Number, which means that the wildcard has an upper bound of Number. Thus, the unknown type argument must be either Number or a subclass of Number. With the parameter type shown here, method sum can receive an ArrayList argument that contains any type of Number, such as ArrayList< Integer > (line 20), ArrayList< Double > (line 33) or ArrayList< Number > (line 46).
[Page 898]
Lines 1120 create and initialize an ArrayList< Integer > called integerList, output its elements and total its elements by calling method sum (line 20). Lines 2433 perform the same operations for an ArrayList< Double > called doubleList. Lines 3746 perform the same operations for an ArrayList< Number > called numberList that contains both Integers and Doubles.
In method sum (lines 5059), although the ArrayList argument's element types are not directly known by the method, they are known to be at least of type Number because the wildcard was specified with the upper bound Number. For this reason, line 56 is allowed because all Number objects have a doubleValue method.
Although wildcards provide flexibility when passing parameterized types to a method, they also have some disadvantages. Because the wildcard (?) in the method's header (line 50) does not specify a type parameter name, you cannot use it as a type name throughout the method's body (i.e., you cannot replace Number with ? in line 55). If the wildcard is specified without an upper bound, then only the methods of type Object can be invoked on values of the wildcard type. Also, methods that use wildcards in their parameter's type arguments cannot be used to add elements to a collection referenced by the parameter.
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.
[Page 898 (continued)]
18.9. Generics and Inheritance: Notes
Generics can be used with inheritance in several ways:
A generic class can be derived from a non-generic class. For example, the Object class is a direct or indirect superclass of every generic class.
A generic class can be derived from another generic class. For example, generic class Stack (in
package java.util) is a subclass of generic class Vector (in package java.util). We discuss these classes in Chapter 19, Collections.
A non-generic class can be derived from a generic class. For example, non-generic class
Properties (in package java.util) is a subclass of generic class Hashtable (in package java.util). We also discuss these classes in Chapter 19.
Finally, a generic method in a subclass can override a generic method in a superclass if both methods have the same signatures.
[Page 898 (continued)]
18.10. Wrap-Up
This chapter introduced J2SE 5.0's new generics capability. You learned how to declare generic methods and classes. You learned how J2SE 5.0 achieves backwards compatibility via raw types. You also learned how to use wildcards in a generic method or a generic class. In the next chapter, we demonstrate the interfaces, classes and algorithms of the Java collections framework. As you will see, the collections presented all use the generics capabilties you learned here.
[Page 899]
18.11. Internet and Web Resources
www.jcp.org/aboutJava/communityprocess/review/jsr014/
Java Community Process download page for the generics specification document Adding Generics to the Java Programming Language: Public Draft Specification, Version 2.0 .
java.sun.com/j2se/5.0/pdf/generics-tutorial.pdf
The tutorial Generics in the Java Programming Language by Gilad Bracha (the specification lead for JSR14 and a reviewer of this book) introduces generics concepts with sample code snippets.
today.java.net/pub/a/today/2003/12/02/explorations.html
today.java.net/pub/a/today/2004/01/15/wildcards.html
The articles Explorations: Generics, Erasure, and Bridging and Explorations: Wildcards in the Generics Specification, each by William Grosso, overview generics features and how to use wildcards.
[Page 899 (continued)]
Summary
Generic methods enable programmers to specify, with a single method declaration, a set of related methods.
Generic classes enable programmers to specify, with a single class declaration, a set of related types.
Generic methods and classes are among Java's most powerful capabilities for software reuse with compile-time type safety.
Overloaded methods are often used to perform similar operations on different types of data.
When the compiler encounters a method call, it always attempts to locate a method declaration
that has the same method name and parameters that match the argument types in the method call.
If the operations performed by several overloaded methods are identical for each argument type,
the overloaded methods can be more compactly and conveniently coded using a generic method. You can write a single generic method declaration, which can be called with arguments of different data types. Based on the types of the arguments passed to the generic method, the compiler handles each method call appropriately.
All generic method declarations have a type parameter section delimited by angle brackets (< and >) that precedes the method's return type.
Each type parameter section contains one or more type parameters (also called formal type parameters) separated by commas.
A type parameter, also known as type variable, is an identifier that specifies a generic type
name. The type parameters can be used as the return type, parameter types and local variable types in a generic method declaration, and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments. Type parameters can represent only reference types.
The names used for type parameters throughout the method declaration must match those
declared in the type parameter section. The name of a type parameter can be declared only once in the type parameter section but can appear more than once in the method's parameter list. Type parameter names need not be unique among different generic methods.
When the compiler encounters a method call, it first determines the argument types and
attempts to locate a method with the same name that specifies parameters that match the argument types. If there is no such method, the compiler determines whether there is an inexact but applicable match.
The relational operator > cannot be used with reference types. However, it is possible to compare two objects of the same class if that class implements the generic interface Comparable (package java.lang).
[Page 900]
Comparable objects have a compareTo method that must return 0 if the objects are equal, -1 if the first object is less than the second or 1 if the first object is greater than the second.
All the type-wrapper classes for primitive types implement Comparable.
Wildcard type arguments enable you to specify method parameters, return values, variables, etc.
that act as supertypes of parameterized types. A wildcard type argument is denoted by the question mark (?), which represents an "unknown type." A wildcard can also have an upper bound.
Because a wildcard (?) is not a type parameter name, you cannot use it as a type name throughout a method's body.
If a wildcard is specified without an upper bound, then only the methods of type Object can be invoked on values of the wildcard type.
Methods that use wildcards as type arguments cannot be used to add elements to a collection referenced by the parameter.
A generic class can be derived from a non-generic class. For example, Object is a direct or indirect superclass of every generic class.
A generic class can be derived from another generic class.
A non-generic class can be derived from a generic class.
A generic method in a subclass can override a generic method in a superclass if both methods have the same signatures.
[Page 901 (continued)]
Terminology
? (wildcard type argument) actual type arguments
add method of ArrayList angle brackets (< and >)
ArrayList class
Comparable<T> interface
compareTo method of Comparable<T>
default upper bound (Object) of a type parameter
Double class
doubleValue method of Number erasure
formal type parameter generics
generic class generic interface generic method
Integer class
Java Collections Framework
Number class
overloaded a generic method parameterized class parameterized type
raw type
scope of a type parameter toString method of ArrayList type argument
type parameter
type parameter scope type parameter section type variable
upper bound of a type parameter upper bound of a wildcard wildcard ( ? )
wildcard as a type argument wildcard without an upper bound
[Page 901 (continued)]
Self-Review Exercises
18.1 State whether each of the following is true or false. If false, explain why.
a.A generic method cannot have the same method name as a non-generic method.
b.All generic method declarations have a type parameter section that immediately precedes the method name.
c.A generic method can be overloaded by another generic method with the same method name but different method parameters.
d.A type parameter can be declared only once in the type parameter section but can appear more than once in the method's parameter list.
e.Type parameter names among different generic methods must be unique.
f.The scope of a generic class's type parameter is the entire class except its static members.
[Page 902]
18.2 Fill in the blanks in each of the following:
a.__________ and __________ enable programmers to specify, with a single method declaration, a set of related methods, or with a single class declaration, a set of related types, respectively.
b.A type parameter section is delimited by __________.
c.The __________ of a generic method can be used to specify the types of the arguments to the method, to specify the return type of the method and to declare variables within the method.
d.The statement "Stack objectStack = new Stack();" indicates that objectStack stores __________.
e.In a generic class declaration, the class name is followed by a(n)
__________.
f.The syntax __________ specifies that the upper bound of a wildcard is type
E.
