Movatterモバイル変換


[0]ホーム

URL:


Documentation

The Java™ Tutorials
Generics (Updated)
Why Use Generics?
Generic Types
Raw Types
Generic Methods
Bounded Type Parameters
Generic Methods and Bounded Type Parameters
Generics, Inheritance, and Subtypes
Type Inference
Wildcards
Upper Bounded Wildcards
Unbounded Wildcards
Lower Bounded Wildcards
Wildcards and Subtyping
Wildcard Capture and Helper Methods
Guidelines for Wildcard Use
Type Erasure
Erasure of Generic Types
Erasure of Generic Methods
Effects of Type Erasure and Bridge Methods
Non-Reifiable Types
Restrictions on Generics
Questions and Exercises
Trail: Learning the Java Language
Lesson: Generics (Updated)
Home Page >Learning the Java Language >Generics (Updated)
« Previous • Trail • Next »

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.
SeeDev.java for updated tutorials taking advantage of the latest releases.
SeeJava Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.
SeeJDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.

Generic Types

Ageneric type is a generic class or interface that is parameterized over types. The followingBox class will be modified to demonstrate the concept.

A Simple Box Class

Begin by examining a non-genericBox class that operates on objects of any type. It needs only to provide two methods:set, which adds an object to the box, andget, which retrieves it:

public class Box {    private Object object;    public void set(Object object) { this.object = object; }    public Object get() { return object; }}

Since its methods accept or return anObject, you are free to pass in whatever you want, provided that it is not one of the primitive types. There is no way to verify, at compile time, how the class is used. One part of the code may place anInteger in the box and expect to getIntegers out of it, while another part of the code may mistakenly pass in aString, resulting in a runtime error.

A Generic Version of the Box Class

Ageneric class is defined with the following format:

class name<T1, T2, ..., Tn> { /* ... */ }

The type parameter section, delimited by angle brackets (<>), follows the class name. It specifies thetype parameters (also calledtype variables)T1,T2, ..., andTn.

To update theBox class to use generics, you create ageneric type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable,T, that can be used anywhere inside the class.

With this change, theBox class becomes:

/** * Generic version of the Box class. * @param <T> the type of the value being boxed */public class Box<T> {    // T stands for "Type"    private T t;    public void set(T t) { this.t = t; }    public T get() { return t; }}

As you can see, all occurrences ofObject are replaced byT. A type variable can be anynon-primitive type you specify: any class type, any interface type, any array type, or even another type variable.

This same technique can be applied to create generic interfaces.

Type Parameter Naming Conventions

By convention, type parameter names are single, uppercase letters. This stands in sharp contrast to the variablenaming conventions that you already know about, and with good reason: Without this convention, it would be difficult to tell the difference between a type variable and an ordinary class or interface name.

The most commonly used type parameter names are:

You'll see these names used throughout the Java SE API and the rest of this lesson.

Invoking and Instantiating a Generic Type

To reference the genericBox class from within your code, you must perform ageneric type invocation, which replacesT with some concrete value, such asInteger:

Box<Integer> integerBox;

You can think of a generic type invocation as being similar to an ordinary method invocation, but instead of passing an argument to a method, you are passing atype argumentInteger in this case — to theBox class itself.


Type Parameter and Type Argument Terminology: Many developers use the terms "type parameter" and "type argument" interchangeably, but these terms are not the same. When coding, one provides type arguments in order to create a parameterized type. Therefore, theT inFoo<T> is a type parameter and theString inFoo<String> f is a type argument. This lesson observes this definition when using these terms.

Like any other variable declaration, this code does not actually create a newBox object. It simply declares thatintegerBox will hold a reference to a "Box ofInteger", which is howBox<Integer> is read.

An invocation of a generic type is generally known as aparameterized type.

To instantiate this class, use thenew keyword, as usual, but place<Integer> between the class name and the parenthesis:

Box<Integer> integerBox = new Box<Integer>();

The Diamond

In Java SE 7 and later, you can replace the type arguments required to invoke the constructor of a generic class with an empty set of type arguments (<>) as long as the compiler can determine, or infer, the type arguments from the context. This pair of angle brackets, <>, is informally calledthe diamond. For example, you can create an instance ofBox<Integer> with the following statement:

Box<Integer> integerBox = new Box<>();

For more information on diamond notation and type inference, seeType Inference.

Multiple Type Parameters

As mentioned previously, a generic class can have multiple type parameters. For example, the genericOrderedPair class, which implements the genericPair interface:

public interface Pair<K, V> {    public K getKey();    public V getValue();}public class OrderedPair<K, V> implements Pair<K, V> {    private K key;    private V value;    public OrderedPair(K key, V value) {this.key = key;this.value = value;    }    public K getKey(){ return key; }    public V getValue() { return value; }}

The following statements create two instantiations of theOrderedPair class:

Pair<String, Integer> p1 = new OrderedPair<String, Integer>("Even", 8);Pair<String, String>  p2 = new OrderedPair<String, String>("hello", "world");

The code,new OrderedPair<String, Integer>, instantiatesK as aString andV as anInteger. Therefore, the parameter types ofOrderedPair's constructor areString andInteger, respectively. Due toautoboxing, it is valid to pass aString and anint to the class.

As mentioned inThe Diamond, because a Java compiler can infer theK andV types from the declarationOrderedPair<String, Integer>, these statements can be shortened using diamond notation:

OrderedPair<String, Integer> p1 = new OrderedPair<>("Even", 8);OrderedPair<String, String>  p2 = new OrderedPair<>("hello", "world");

To create a generic interface, follow the same conventions as for creating a generic class.

Parameterized Types

You can also substitute a type parameter (that is,K orV) with a parameterized type (that is,List<String>). For example, using theOrderedPair<K, V> example:

OrderedPair<String,Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));
« PreviousTrailNext »

About Oracle |Contact Us |Legal Notices |Terms of Use |Your Privacy Rights

Copyright © 1995, 2024 Oracle and/or its affiliates. All rights reserved.

Previous page: Why Use Generics?
Next page: Raw Types

[8]ページ先頭

©2009-2025 Movatter.jp