M
Mike Schilling
Putting the following down on paper (OK, pixels) helped me to understand how
generics extend the Java type system. Since I haven't seen any texts that
look at things in quite this fashion, I thought I'd post it on the chance
that it would help others as well. Note that this only discusses object
types, not primitives, since it's describes the ability to refer to an
object of type A by a reference of type B, with B a supertype of A. It also
doesn't discuss conversions of the sort found in
float f = 2;
or
Integer i = 12;
In both cases, the entity on the right-hand side is converted to an entity
of a different type, quite different from what happens in
Object o = "hello";
in which the left hand-side is made to refer to precisely the entity that is
the right-hand side. OK, here we go:
The assignment statement in Java looks like
reference = expression;
This is legal whenever the type R of the reference is a supertype of the
type E of the expression, where "supertype" is defined so that, for all
types T, T is a supertype of itself. (As mentioned above, we're going to
ignore primitives and built-in conversion.) Before generics, the rules for
supertype were relatively simple:
1. T is a supertype of T
2. If T is a class other then Object, T's superclass is a supertype of T
3. Object is a supertype of all interfaces and array types
4. All interfaces that T implements or extends are supertypes of T
5. If T is a supertype of U:
T[] is a supertype of U[] (i.e. arrays are covariant)
6. If T is a supertype of U and U is a supertype of V, then T is a
supertype if V (i.e. "supertype" is transitive)
There rules are all pretty clear, even if you don't ordinarily think of them
that way.
Generics complicate this somewhat, by adding these extra rules.
If T is a supertype of U, and A is a supertype of B:
1. A<T> is a supertype of B<T>
2. A<T> is not a supertype of A<U> (i.e. generics are not covariant)
3. T is a supertype of <? extends T>
4. There is no type V for which <? extends T> is a supertype of V
5. <? super T> is a supertype of T
6. The only supertype of <? super T> is Object
7. A<? extends T> is a supertype of A<? extends U>
8. A<? super U> is a supertype of A<? super T>
generics extend the Java type system. Since I haven't seen any texts that
look at things in quite this fashion, I thought I'd post it on the chance
that it would help others as well. Note that this only discusses object
types, not primitives, since it's describes the ability to refer to an
object of type A by a reference of type B, with B a supertype of A. It also
doesn't discuss conversions of the sort found in
float f = 2;
or
Integer i = 12;
In both cases, the entity on the right-hand side is converted to an entity
of a different type, quite different from what happens in
Object o = "hello";
in which the left hand-side is made to refer to precisely the entity that is
the right-hand side. OK, here we go:
The assignment statement in Java looks like
reference = expression;
This is legal whenever the type R of the reference is a supertype of the
type E of the expression, where "supertype" is defined so that, for all
types T, T is a supertype of itself. (As mentioned above, we're going to
ignore primitives and built-in conversion.) Before generics, the rules for
supertype were relatively simple:
1. T is a supertype of T
2. If T is a class other then Object, T's superclass is a supertype of T
3. Object is a supertype of all interfaces and array types
4. All interfaces that T implements or extends are supertypes of T
5. If T is a supertype of U:
T[] is a supertype of U[] (i.e. arrays are covariant)
6. If T is a supertype of U and U is a supertype of V, then T is a
supertype if V (i.e. "supertype" is transitive)
There rules are all pretty clear, even if you don't ordinarily think of them
that way.
Generics complicate this somewhat, by adding these extra rules.
If T is a supertype of U, and A is a supertype of B:
1. A<T> is a supertype of B<T>
2. A<T> is not a supertype of A<U> (i.e. generics are not covariant)
3. T is a supertype of <? extends T>
4. There is no type V for which <? extends T> is a supertype of V
5. <? super T> is a supertype of T
6. The only supertype of <? super T> is Object
7. A<? extends T> is a supertype of A<? extends U>
8. A<? super U> is a supertype of A<? super T>