Core Java Tutorials


Java Hello World

Java Compilation

JDK New Features

JVM Architecture

Java OOPs Concepts

Java Package


Exception Handling


Immutable Class

File Handling




Concurrent Package


Collection Internal



Reflection In Java


Class Loader

Java Inner classes

Garbage Collector


References In Java

Heap Dump & Thread Dump

Subtyping in Generics

In Java, as in other object-oriented typed languages, hierarchies of types can be built:

In Java, a subtype of a type T is either a type that extends T or a type that implements T (if T is an interface) directly or indirectly. Since "being subtype of" is a transitive relation, if a type A is a subtype of B and B is a subtype of C, then A will be a subtype of C too. In the figure above:
 Apple is a subtype of Fruit
 Fruit is a subtype of Food
 Apple is a subtype of Food.

Every Java type will also be subtype of Object. Every subtype A of a type B may be assigned to a reference of type B:
class Fruit {
class Apple extends Fruit {
Apple a =new Apple();
Fruit f = a; //super class can reference object of sub class.

Subtyping of Generic Types

If a reference of an Apple instance can be assigned to a reference of a Fruit, as seen above, then what's the relation between, let's say, a List<Apple> and a List<Fruit>? Which one is a subtype of which? More generally, if a type A is a subtype of a type B, how does C<A> and C<B> relate themselves?

Surprisingly, the answer is: in no way. In more formal words, the subtyping relation between generic types is invariant.

This means that the following code snippet is invalid:
List<Apple> fruitsApple = new ArrayList<Apple>();
List<Fruit> fruits = fruitsApple;//List of Apple cannot be assigned into List of Fruit type

 Why subtyping relation between generic types is invariant?