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.

Generics, Inheritance, and Subtypes

As you already know, it is possible to assign an object of one type to an object of another type provided that the types are compatible. For example, you can assign anInteger to anObject, sinceObject is one ofInteger's supertypes:

Object someObject = new Object();Integer someInteger = new Integer(10);someObject = someInteger;   // OK

In object-oriented terminology, this is called an "is a" relationship. Since anIntegeris a kind ofObject, the assignment is allowed. ButInteger is also a kind ofNumber, so the following code is valid as well:

public void someMethod(Number n) { /* ... */ }someMethod(new Integer(10));   // OKsomeMethod(new Double(10.1));   // OK

The same is also true with generics. You can perform a generic type invocation, passingNumber as its type argument, and any subsequent invocation ofadd will be allowed if the argument is compatible withNumber:

Box<Number> box = new Box<Number>();box.add(new Integer(10));   // OKbox.add(new Double(10.1));  // OK

Now consider the following method:

public void boxTest(Box<Number> n) { /* ... */ }

What type of argument does it accept? By looking at its signature, you can see that it accepts a single argument whose type isBox<Number>. But what does that mean? Are you allowed to pass inBox<Integer> orBox<Double>, as you might expect? The answer is "no", becauseBox<Integer> andBox<Double> are not subtypes ofBox<Number>.

This is a common misunderstanding when it comes to programming with generics, but it is an important concept to learn.

diagram showing that Box<Integer> is not a subtype of Box<Number>
Box<Integer> is not a subtype ofBox<Number> even thoughInteger is a subtype ofNumber.

Note: Given two concrete typesA andB (for example,Number andInteger),MyClass<A> has no relationship toMyClass<B>, regardless of whether or notA andB are related. The common parent ofMyClass<A> andMyClass<B> isObject.

For information on how to create a subtype-like relationship between two generic classes when the type parameters are related, seeWildcards and Subtyping.

Generic Classes and Subtyping

You can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by theextends andimplements clauses.

Using theCollections classes as an example,ArrayList<E> implementsList<E>, andList<E> extends Collection<E>. SoArrayList<String> is a subtype ofList<String>, which is a subtype ofCollection<String>. So long as you do not vary the type argument, the subtyping relationship is preserved between the types.

diagram showing a sample collections hierarchy: ArrayList<String> is a subtype of List<String>, which is a subtype of Collection<String>.
A sampleCollections hierarchy

Now imagine we want to define our own list interface,PayloadList, that associates an optional value of generic typeP with each element. Its declaration might look like:

interface PayloadList<E,P> extends List<E> {  void setPayload(int index, P val);  ...}

The following parameterizations ofPayloadList are subtypes ofList<String>:

diagram showing an example PayLoadList hierarchy: PayloadList<String, String> is a subtype of List<String>, which is a subtype of Collection<String>. At the same level of PayloadList<String,String> is PayloadList<String, Integer> and PayloadList<String, Exceptions>.
A samplePayloadList hierarchy
« 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: Generic Methods and Bounded Type Parameters
Next page: Type Inference

[8]ページ先頭

©2009-2025 Movatter.jp