2015-10-17 58 views
4

这是思维在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版本 “1.8.0_60”
  2. 的Java(TM)SE运行时环境(建1.8。 0_60-b27)
  3. Java HotSpot(TM)64位服务器虚拟机(版本25.60-b23,混合模式)
+3

因为不应该有一个。 'Light'和'Heavy'是Snow的子类,因此可以添加到'Snow'的List中。 – hotzst

+1

在Java 7中,此代码给我一个编译错误 - '类型不匹配:无法从列表转换为列表'。 – Eran

回答

6

其实这本书是对的。这里的区别是Java版本。

Thinking in Java针对Java 5/6(根据封面)。对于这个版本的Java(也包括Java 7),该代码段将不会与javac一起编译。错误是:

不兼容的类型:java.util.List<Powder>不能转换到java.util.List<Snow>

在Java 8所示,该编译就好:类型推测系统进行了改进。

2

这本书显然希望编译器确定右边的类型为List<Powder>,它不是List<Snow>。但是,由于Arrays.<T>asList(T ...)对于T有其自己的范围,因此编译器能够推断出正确的边界应该是Snow并且LightHeavy都是Snow

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

相关问题