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.
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)); // OKThe 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.

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.

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>:

About Oracle |Contact Us |Legal Notices |Terms of Use |Your Privacy Rights
Copyright © 1995, 2024 Oracle and/or its affiliates. All rights reserved.