Why are array assignments incompatible, even though their data types are?

前端 未结 2 1396
时光说笑
时光说笑 2021-01-20 18:41
byte b =10;   
int a = b;   // Primitive data type widening
             // Works perfectly fine

the above code will give no error/warnings. But wh

2条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-20 19:05

    The language spec defines subtyping between array types in Sec 4.10.3:

    The following rules define the direct supertype relation among array types:

    • If S and T are both reference types, then S[] >1 T[] iff S >1 T.

    • Object >1 Object[]

    • Cloneable >1 Object[]

    • java.io.Serializable >1 Object[]

    • If P is a primitive type, then:

      • Object >1 P[]

      • Cloneable >1 P[]

      • java.io.Serializable >1 P[]

    The final bullets ("If P is a primitive type...") show that the language does not define any relationship between arrays of differing primitive types. The only valid assignments are:

    byte[] bs = new byte[10];
    
    byte[] bs2 = bs;
    Object obj = bs;
    Cloneable cl = bs;
    Serializable ser = bs;
    

    This doesn't provide an answer as to why it is like this; you'd have to ask the language designers. However, simple examples like that shown by Eran demonstrate why it would not be safe to do as OP proposes.

    It should be noted that the first line - which permits an assignment like

    Object[] obj = new String[10];
    obj[0] = new Object();  // ArrayStoreException!
    

    was a design error: that arrays are covariant makes them not type safe. This is one reason to strongly prefer generics to arrays, since generics are invariant, and so prevent such assignments.

提交回复
热议问题