我不能百分百理解为什么下面的代码不起作用:

package org.example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {

    public interface MyInt<E> {
    }

    public static final class MyNum<E> implements MyInt<E> {
        private E privados;
    }

    public static void f(List<? extends MyInt> l) {
        System.out.println("from List<?>");
    }

    public static void main(String[] args) {
        var m = new MyNum();
        List<MyNum> l = Arrays.asList(m);

        ArrayList<MyInt> r = l.stream().collect(Collectors.toCollection(ArrayList<MyInt>::new));
        f(r);
        f(l.stream().collect(Collectors.toCollection(ArrayList<MyInt>::new)));
    }
}

传递L值的调用f(r)可以工作,但对下一行中的r值版本的调用不能.

很明显,当程序员强制执行特定的ArrayList<MyInt>时,编译器中发生的约束求解过程是愉快的,但当我们通过将collect的结果直接传递给f来要求它端到端进行约束求解时,编译器将发送如下错误:

java: incompatible types: inferred type does not conform to upper bound(s)
    inferred: java.lang.Object&java.util.List<? extends org.example.Main.MyInt>&java.util.Collection<org.example.Main.MyNum>
    upper bound(s): java.util.Collection<org.example.Main.MyNum>,java.util.List<? extends org.example.Main.MyInt>,java.lang.Object

推断的上限与上限之间的唯一区别(从错误消息):

  1. &,的用法
  2. 对象的顺序(反转)

我假设顺序并不重要(它们是集合),&,具有特殊的意义.

有人对正在发生的事情有更彻底的、不那么"挥手"的解释吗?

推荐答案

这种推理不一致是由lambda表达式引起的.你可以在this mail on OpenJDK.com(主题:JDK-8219318 (???): inferred type does not conform to upper bound(s) when collecting to a HashMap)中获得解释.

也许新的Java编译器(Javac)已经解决了这个问题.

如果添加显式类型,这个问题就可以解决.例如:

f((ArrayList<? extends MyInt>) l.stream().collect(Collectors.toCollection(ArrayList<MyInt>::new)));

f((ArrayList<MyInt>) l.stream().collect(Collectors.toCollection(ArrayList<MyInt>::new)));

f((List<? extends MyInt>) l.stream().collect(Collectors.toCollection(ArrayList<MyInt>::new)));

f((List<MyInt>) l.stream().collect(Collectors.toCollection(ArrayList<MyInt>::new)));

此外,您还可以提供供应商的实现.在这种情况下,您不需要添加显式类型.匿名类示例:

f(l.stream().collect(Collectors.toCollection(new Supplier<List<MyInt>>(){
   @Override
   public List<MyInt> get() {
   return new ArrayList<MyInt>();
  }
})));

Java相关问答推荐

在Java 8之后,HashMap的最坏情况下时间复杂度仍然是O(n)而不是O(log n)?

Java应用程序崩溃时试图读取联系人从电话

H2弹簧靴试验跌落台

了解Android Studio中的调试器输出

如果一个子类没有构造函数,超类也没有构造函数,那么为什么我可以构造子类的实例呢?

使用java访问具体子类特定方法的最佳方法是什么?

Hibernate EmptyInterceptor可以工作,但不能拦截器

在AVL树的Remove方法中使用NoSuchElementException时遇到问题

如何让DTO接受空字符串字段,但如果它们不为空,则应用JPA验证?

如何在不删除Java中已有内容的情况下覆盖文件内容?

解析方法";javax/imageio/metadata/IIOMetadata.getAsTree(Ljava/lang/String;)Lorg/w3c/dom/Node时加载约束冲突

在Oracle JDBC连接中,连接失效和身份验证失效是什么意思?

如何创建模块信息类文件并将其添加到JAR中?

具有多个模式的DateTimeForMatter的LocalDate.parse失败

如何通过Java java.lang.Foreign API访问本机字节数组

在Oracle中调用输出参数在索引处缺少IN或OUT参数的函数

在权限列表中找不到我的应用程序

如何使用jOOQ在PostgreSQL中从枚举类型生成Java枚举

Java泛型方法重载

MapStruct记录到记录的映射不起作用