Core Java Tutorials


Introduction

Java Hello World

Java Compilation

JDK New Features

JVM Architecture

Java OOPs Concepts

Java Package

Array

Exception Handling

String

Immutable Class

File Handling

Serialization

MultiThreading

Volatile

Concurrent Package

Collection

Collection Internal

Generics

Cloning

Reflection In Java

Annotation

Class Loader

Java Inner classes

Garbage Collector

JDBC

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?