关于java中Arrays.asList()方法生成类型的问题

**Thingking in Java第11章holding your object中有一段代码
**

 //: holding/AsListInference.java
// Arrays.asList() makes its best guess about type.
import java.util.*;
class Snow {}
class Powder extends Snow {}
class Light extends Powder {}
class Heavy extends Powder {}
class Crusty extends Snow {}
class Slush extends Snow {}
public class AsListInference {
public static void main(String[] args) {
List<Snow> snow1 = Arrays.asList(
new Crusty(), new Slush(), new Powder());
// Won’t compile:
// List<Snow> snow2 = Arrays.asList(
// new Light(), new Heavy());
// Compiler says:
// found : java.util.List<Powder>
// required: java.util.List<Snow>
// Collections.addAll() doesn’t get confused:
List<Snow> snow3 = new ArrayList<Snow>();
Collections.addAll(snow3, new Light(), new Heavy());
280 Thinking in Java Bruce Eckel
 // Give a hint using an
// explicit type argument specification:
List<Snow> snow4 = Arrays.<Snow>asList(
new Light(), new Heavy());
}
} ///:~

注释部分有语句

// Won’t compile:
// List<Snow> snow2 = Arrays.asList(
// new Light(), new Heavy());
// Compiler says:
// found : java.util.List<Powder>
// required: java.util.List<Snow>

书中的说法是

When trying to create snow2, Arrays.asList( ) only has types of Powder, so it creates a List rather than a List

但是我把注释去掉之后编译运行后并没有任何报错.难道asList没有生成List<'Power>而是List<'Snow>?

1个回答

是的,你的猜想是正确的.java并不是真正的泛型,而是通过擦除来实现伪泛型,也就是只有编译时的泛型检查,而没有运行时的泛型转换.编译时
new Light(), new Heavy()的最近的直接父类是Power,Arrays.asList自动推导的;类型就是Power而不是Snow.所以上面注释的代码对编译器来说等价于:
List tmp = Arrays.asList(new Light(), new Heavy());
List = tmp;//这类似于String s = 123;一样的问题.编译器能够发现这样的问题,但由于安全原因.不能给出修正;这相比于C#的泛型协变和逆变就弱的太多啦

fantastic_ying
Fantastic_Ying 也就是说snow2 并不是一个真正的List<Snow>?
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!