Array and generic rule type in Java

In the last paragraph of paragraph 25 in Effective Java (2nd), he said:

Arrays and generics have very different type rules. Arrays are covariant and reified ; generics invariant and erased.

Can someone give clearer definitions of bold terms regarding arrays and generics in Java? I would not mind some examples either.

+4
source share
1 answer

You did not mention whether you were confused in a certain concept, so I will try to just give the basic definitions of covariance and invariance.

Covariance preserves the order of types; invariance does not. This means that subtyping is or is not preserved (inverted in case of contravariance).

So, if you had the following class

public class A { public void go() { System.out.println("A"); } } 

and...

 public class B extends A { @Override public void go() { System.out.println("B"); } } 

With covariant typing (e.g. arrays) function

 public static void go(A[] as) { for (A a : as) a.go(); } 

acts great like

 A[] as = new A[8]; B[] bs = new B[8]; go(as); go(bs); 

In other words, array types are exposed to the runtime or reified.

With invariant typing (for example, generics), subtyping is not preserved. So, for example, X<B> has no relation of type to X<A> , except for X This is partly due to the fact that generic types are not exposed to the runtime or are erased.

However, you can still explicitly express covariance and contravariance in Java using extends and super respectively. For example, with a class

 public class X<T extends A> { private T t_; public X(T t) { t_ = t; } public void go() { t_.go(); } } 

Function

 public static void go(X<?> x) { x.go(); } 

will be used as

 X<A> xa = new X<A>(a); X<B> xb = new X<B>(b); go(xa); go(xb); 
+4
source

All Articles