Why are arrays covariant but generics are invariant?

前端 未结 9 1260
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 00:44

From Effective Java by Joshua Bloch,

  1. Arrays differ from generic type in two important ways. First arrays are covariant. Generics are invariant.
  2. Cov

9条回答
  •  再見小時候
    2020-11-22 01:09

    An important feature of parametric types is the ability to write polymorphic algorithms, i.e. algorithms that operate on a data structure regardless of its parameter value, such as Arrays.sort().

    With generics, that's done with wildcard types:

    > void sort(E[]);
    

    To be truly useful, wildcard types require wildcard capture, and that requires the notion of a type parameter. None of that was available at the time arrays were added to Java, and makings arrays of reference type covariant permitted a far simpler way to permit polymorphic algorithms:

    void sort(Comparable[]);
    

    However, that simplicity opened a loophole in the static type system:

    String[] strings = {"hello"};
    Object[] objects = strings;
    objects[0] = 1; // throws ArrayStoreException
    

    requiring a runtime check of every write access to an array of reference type.

    In a nutshell, the newer approach embodied by generics makes the type system more complex, but also more statically type safe, while the older approach was simpler, and less statically type safe. The designers of the language opted for the simpler approach, having more important things to do than closing a small loophole in the type system that rarely causes problems. Later, when Java was established, and the pressing needs taken care of, they had the resources to do it right for generics (but changing it for arrays would have broken existing Java programs).

提交回复
热议问题