是Object数组的String数组子类吗?

Kal*_*Kal 7 java arrays collections

我想我错过了一些基本的东西.对先前提出的问题的任何解释或指示将非常有帮助.

import java.util.Arrays;
import java.util.List;

public class St {

    public static void bla(Object[] gaga) {
            gaga[0] = new Date(); // throws ArrayStoreException
        System.out.println(gaga[0]);
    }

    public static void bla(List<Object> gaga) {
        System.out.println(gaga.get(0));
    }

    public static void main(String[] args) {
            String[] nana = { "bla" };
        bla(nana); // Works fine

        List<String> bla1 = Arrays.asList(args);
        bla(bla1); // Wont compile

            System.out.println(new String[0] instanceof Object[]); // prints true
            System.out.println(nana.getClass().getSuperclass().getSimpleName()); // prints Object
    }

}
Run Code Online (Sandbox Code Playgroud)

所以,似乎a List<String>不是a的子类,List<Object>而a String[]是a的子类Object[].

这是一个有效的假设吗?如果是这样,为什么?如果没有,为什么?

谢谢

Boz*_*zho 10

Java数组是协变的,即它们允许Object[] foo = new String[2];.但这并不意味着它们是子类.String[]是一个子类Object(虽然instanceof返回true,String[].class.getSuperclass()返回Object)


Ita*_*man 5

是的,您的假设是有效的.正如@Bozho所说,数组是协变的,而泛型集合(例如泛型List)不是协变的.

数组中的协方差是有风险的:

String[] strings = new String[] { "a", "b" }
Object[] objects = strings;
objects[0] = new Date();  // <-- Runtime error here 
String s = strings[0];
s.substring(5, 3);        // ????!! s is not a String 
Run Code Online (Sandbox Code Playgroud)

第三行触发运行时异常.如果它没有触发此异常,那么你可以得到一个String变量,s它引用的值不是String(也不是它的子类型):a Date.