为什么此代码中没有类型转换异常?

时间:2015-10-17 11:02:05

标签: java

这是来自 Thinking in Java

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) {
        //The book says it won't compile, but actually it does.
        List<Snow> snow2 = Arrays.asList(new Light(), new Heavy());
    }
}

这是我的Java环境:

  1. java版本&#34; 1.8.0_60&#34;
  2. Java(TM)SE运行时环境(版本1.8.0_60-b27)
  3. Java HotSpot(TM)64位服务器VM(版本25.60-b23,混合模式)

2 个答案:

答案 0 :(得分:6)

实际上,这本书是对的。这里的区别是Java版本。

Thinking in Java针对Java 5/6(根据封面)。对于此版本的Java(以及Java 7),该代码段不会使用javac进行编译。错误是:

  

不兼容的类型:java.util.List<Powder>无法转换为java.util.List<Snow>

使用Java 8,编译得很好:类型推理系统得到了改进。

答案 1 :(得分:2)

本书显然希望编译器将右侧的类型确定为List<Powder>,而不是List<Snow>。但是,由于Arrays.<T>asList(T ...)具有T自己的自包含范围,因此编译器能够推断出正确的边界应为Snow以及Light和{{} 1}}是Heavy

我手边没有Java 7编译器,但Java 8确实在generic type inference中带来了一些改进,这些改进可能是编译器解决这个特定类型绑定的原因。