Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么这种通用赋值是非法的?_Java_Generics_Bounded Wildcard - Fatal编程技术网

Java 为什么这种通用赋值是非法的?

Java 为什么这种通用赋值是非法的?,java,generics,bounded-wildcard,Java,Generics,Bounded Wildcard,我有一门课: class Generic<T> { List<List<T>> getList() { return null; } } 这对我来说似乎很奇怪,因为根据Generic的声明,当调用getList时,创建Generic并获取列表是很自然的 事实上,我需要这样写作业: List<? extends List<? extends Number>> list = tt.getList(); //

我有一门课:

class Generic<T> {
    List<List<T>> getList() {
        return null;
    }
}
这对我来说似乎很奇怪,因为根据
Generic
的声明,当调用
getList
时,创建
Generic
并获取
列表是很自然的

事实上,我需要这样写作业:

List<? extends List<? extends Number>> list = tt.getList(); // this one is correct

List关于您遇到的通配符类型,这是一件棘手但有趣的事情!这是很棘手的,但当你理解它时,它确实是合乎逻辑的

该错误与以下事实有关:通配符
?扩展编号
不是指单个具体类型,而是指某个未知类型。因此出现了两次
?扩展编号不一定引用同一类型,因此编译器不允许赋值

详细说明
  • 赋值的右侧,
    tt.getList()
    ,没有得到类型
    列表当询问您可能要发布的错误时,即确切的消息,理想情况下是堆栈跟踪。这不是运行时异常,只是编译错误。编译错误说明了什么?阅读通配符,事实上,我知道错误消息的意思,我只是想知道为什么编译器认为这个分配是非法的。换句话说,如果它是合法的,会出什么问题呢?就为了我对它感兴趣:你能声明
    var list=tt.getList()
    获取
    列表
    ,或者它不适用于泛型?你是说
    列表
    的子类型吗List@haoyuwang:是的,没错!很抱歉,我犯了一个错误,will fix。@DorianGray:我相信这就像你说的,你可以使用
    var
    来获取一个与捕获类型完全相同的变量。但是我认为你无论如何不能用那种类型做太多…@Lii你能举例说明如果第一次转让是合法的,会发生什么情况吗。只要有助于理解问题,就不必涉及我的案例。(我的情况很糟)。我将不胜感激。
    List<? extends List<? extends Number>> list = tt.getList(); // this one is correct
    
    class Generic<T> {
        private List<List<T>> list = new ArrayList<>();
    
        public List<List<T>> getList() {
            return list;
        }
    }
    
    // Start with a concrete type, which will get corrupted later on
    Generic<Integer> genInt = new Generic<>();
    
    // Add a List<Integer> to genInt.list. This is not necessary for the
    // main example but migh make things a little clearer.
    List<Integer> ints = List.of(1);
    genInt.getList().add(ints); 
    
    // Assign to a wildcard type as in the question
    Generic<? extends Number> genWild = genInt;
    
    // The illegal assignment. This doesn't compile normally, but we force it
    // using an unchecked cast to see what would happen IF it did compile.
    List<List<? extends Number>> list =
        (List<List<? extends Number>>) (Object) genWild.getList();
    
    // This is the crucial step: 
    // It is legal to add a List<Float> to List<List<? extends Number>>.
    // list refers to genInt.list, which has type List<List<Integer>>.
    // Heap pollution occurs!
    List<Float> floats = List.of(1.0f);
    list.add(floats);
    
    // notInts in reality is the same list as floats!
    List<Integer> notInts = genInt.getList().get(1);
    
    // This statement reads a Float from a List<Integer>. A ClassCastException
    // is thrown. The compiler must not allow us to end up here without any
    // previous type errors or unchecked cast warnings.
    Integer i = notInts.get(0);
    
    List<? extends List<? extends Number>> list = tt.getList();