Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

AhmadLang / Java, How To Program, 2004

.pdf
Скачиваний:
626
Добавлен:
31.05.2015
Размер:
51.82 Mб
Скачать

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.

A benefit of implementing interface Comparable is that Comparable objects can be used with the sorting and searching methods of class Collections (package java.util).

When the compiler translates a generic method into Java bytecodes, it removes the type

parameter section and replaces the type parameters with actual types. This process is known as erasure. By default each type parameter is replaced with its upper bound. By default, the upper bound is type Object unless specified otherwise in the type parameter section.

When the compiler performs erasure on a method that returns a type variable, it also inserts

explicit cast operations in front of each method call to ensure that the returned value is of the type expected by the caller.

A generic method may be overloaded. A class can provide two or more generic methods that

specify the same method name but different method parameters. A generic method can also be overloaded by non-generic methods that have the same method name and number of parameters. When the compiler encounters a method call, it searches for the method declaration that most precisely matches the method name and the argument types specified in the call.

When the compiler encounters a method call, it performs a matching process to determine which

method to call. The compiler tries to find and use a precise match in which the method names and argument types of the method call match those of a specific method declaration. If this fails, the compiler determines whether a generic method is available that provides a precise match of the method name and argument types, and if so, uses that generic method.

Generic classes provide a means for describing a class in a type-independent manner. We can then instantiate type-specific objects of the generic class.

A generic class declaration looks like a non-generic class declaration, except that the class name

is followed by a type parameter section. As with generic methods, the type parameter section of a generic class can have one or more type parameters separated by commas.

When a generic class is compiled, the compiler performs erasure on the class's type parameters and replaces them with their upper bounds.

Type parameters cannot be used in a class's static declarations.

When instantiating an object of a generic class, the types specified in angle brackets after the

class name are known as type arguments. They are used by the compiler to replace the type parameters so that the compiler can perform type checking and insert cast operations as necessary.

It is possible to instantiate a generic class without specifying a type argument. In this case, the

new object of the class is said to have a raw type, which means that the compiler implicitly uses type Object (or the type parameter's upper bound) throughout the generic class for each type argument.

The Java Collections Framework provides many generic data structures and algorithms that

manipulate the elements of those data structures. Perhaps the simplest of the data structures is class ArrayLista dynamically resizable, array-like data structure.

Class Number is the superclass of both Integer and Double.

Method add of class ArrayList appends an element to the end of the collection.

Method toString of class ArrayList returns a string of the form"[ elements ]" in which elements is a comma-separated list of the elements' string representations.

Method doubleValue of class Number obtains the Number's underlying primitive value as a double value.

[Page 901]

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.