有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

为什么Java泛型的这种用法不能编译?

就我的一生而言,我无法理解为什么编译器不让我做以下事情

import java.util.HashMap;
import java.util.Map;

public class TestMap {
   private final Map<Integer, ? extends Number> map = new HashMap<Integer, Number>();

   public void put(Integer key, Long item) {
      this.map.put(key, item);
   }
}

为什么第this.map.put(key, item)行会导致编译错误

我知道我可以将map的声明更改为使用Number而不是? extends Number使其工作,但在我看来,我所做的是完全合法的,我更希望不允许map中的Number对象。我正在使用Java1.6.0_13


共 (3) 个答案

  1. # 1 楼答案

    这与泛型协方差有关

    当你申报时

    Map<Integer, ? extends Number> map
    

    例如,您不能保证? extends Number是一个Long,因此无法向映射插入任何内容

    想象一下这种情况:

       Map<Integer, ? extends Number> map = new HashMap<Integer, Integer>();
    
       public void put(Integer key, Long item) {
          this.map.put(key, item);
       }
    

    在这里,Integer != Long,但两者都服从? extends Number

  2. # 2 楼答案

    You can't insert into collections that use wildcard types。这是因为,虽然可以将List<Float>传递给接受List<? extends Number>的方法,但在其中插入Long是不安全的。在您的例子中,由于集合的定义是如此可见,人们可能希望编译器知道得更好,但事实并非如此

  3. # 3 楼答案

    为泛型类型提供通配符可以有效地使其成为只读类型