The covariance of arrays (covariant) refers to:
If class base is the base class for a class sub, then base[] is the base class for sub[].
The generic is immutable (invariant), and the list is not the base class of the list, not its subclasses.
the covariance of arrays can cause some errors, such as the following code:
1234 |
public static void main(String[] args) { Object[] array = new String[ 10 ]; array[ 0 ] = 10 ; } |
It can be compiled through, because the array is covariant, object[] Type references can point to an object of type string[]
However, the following exceptions will be reported when running:
1 |
Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integer |
However, this is not the case for generics:
1234 |
public static void main(String[] args) { List< Object> list = new ArrayList< String>(); list.add( 10 ); } |
This code does not even compile.
2, the embodiment of the array.
Arrays are materialized (reified), while generics are erased at run time (Erasure).
An array is a type constraint that determines the array element at run time.
Generics, by contrast, are erased at run time by the type information of generics, which are only hardened when compiled.
So in the above example, the array method is arraystoreexception in the run times, and generics simply cannot be compiled.
3, generics are not covariant
Although it can be helpful to treat a collection as an abstraction of an array, there are some special properties that the array does not have.
The array in the Java language is covariant (covariant), that is, if an integer expands number (as is the case), not only the integer is number, but also integer[] is number[], in the request number[] Can be passed on or given to integer[]. (more formally, if number is a super-type of integer, then number[] is also a super-type of integer[].
You might think that the same principle applies to generic type--list , which is a super-type of list , so you can pass the list where you want the list . Unfortunately, this is not the case.
There is a good reason not to allow this:
Doing so will break the type-safe generics to be provided.
If you can assign a list to a list .
Then the following code allows non-integer content to be placed in the List
123 |
List<integer> li = new ArrayList<integer>(); List<number> ln = li; // illegal ln.add( new Float( 3.1415 ));</number></integer></integer> |
Because LN is a List , so adding a float to it seems to be perfectly legal. But if Ln is an alias of Li, then this destroys the type-safety commitment contained in the LI definition-it is a list of integers, which is why generic types cannot be covariant.