How do arrays “remember” their types in Java?

前端 未结 5 513
情深已故
情深已故 2021-02-07 02:14

Consider the following code:

class AA { }

class BB extends AA { }

public class Testing {

    public static void main(String[] args) {
        BB[] arr = new B         


        
5条回答
  •  走了就别回头了
    2021-02-07 02:54

    1. Each time a value is stored into an array, the compiler inserts a check. Then at run-time it validates the type of the value is equal to the run-time type of the array.

    2. Generics were introduced. Generics are invariant and can be verified at compile time. (At run-time the generic types are erased).

    3. Here is an example of the failing case (from wikipedia):

    // a is a single-element array of String
    String[] a = new String[1];
    
    // b is an array of Object
    Object[] b = a;
    
    // Assign an Integer to b. This would be possible if b really were
    // an array of Object, but since it really is an array of String,
    // we will get a java.lang.ArrayStoreException.
    b[0] = 1;
    

    The compiler cannot detect that the third statement will result in an ArrayStoreException. With regard to the third statement, the compiler sees that we are adding an Integer to an Object[] array. This is perfectly legal.

    Background / Reasoning (from wikipedia)

    Early versions of Java and C# did not include generics (a.k.a. parametric polymorphism). In such a setting, making arrays invariant rules out useful polymorphic programs. For example, consider writing a function to shuffle an array, or a function that tests two arrays for equality using the Object.equals method on the elements. The implementation does not depend on the exact type of element stored in the array, so it should be possible to write a single function that works on all types of arrays. It is easy to implement functions of type

    boolean equalArrays (Object[] a1, Object[] a2);
    void shuffleArray(Object[] a);
    

    However, if array types were treated as invariant, it would only be possible to call these functions on an array of exactly the type Object[]. One could not, for example, shuffle an array of strings.

    Therefore, both Java and C# treat array types covariantly. For instance, in C# string[] is a subtype of object[], and in Java String[] is a subtype of Object[]

提交回复
热议问题