原因是数组是“协变式”的, 比如,如果 T 是S 的一个子类型, 那么 T[] 就会是 S[] 的一个子类型. Joshua Bloch 在其著作 Effective Java 涵盖了所有的理论, 每一个Java开发者必读.
归因于这个行为,暴露数组类型的接口允许返回声明数组类型的一个子类型, 导致了一个怪异的运行时异常.
Bloch 同时也解释说,数组与泛型类型不兼容. 因为数组会在运行时强制要求有类型信息,而泛型则会在编译时被检查,泛型类型不能被放到数组中.
一般而言,数组和泛型不能很好的融合。如果你发现自己在融合它们而得到了一个编译时错误或者警告,那你的第一反应应该是用list去替换数组.
- Joshua Bloch, Effective Java (第二版), 第29条
总结数组底层的语言构造、它们会被用在实现中,但是它们不应该想其它的类暴露. 在一个接口方法中使用数组违背了面向对象的原则,它会导致违和的API,并且它也可能给类型安全和性能造成短板.