gpt4 book ai didi

java - 推理变量具有不兼容的界限。 Java 8 编译器回归?

转载 作者:IT老高 更新时间:2023-10-28 20:47:28 24 4
gpt4 key购买 nike

以下程序在 Java 7 和 Eclipse Mars RC2 for Java 8 中编译:

import java.util.List;

public class Test {

static final void a(Class<? extends List<?>> type) {
b(newList(type));
}

static final <T> List<T> b(List<T> list) {
return list;
}

static final <L extends List<?>> L newList(Class<L> type) {
try {
return type.newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}

使用javac 1.8.0_45编译,报如下编译错误:

Test.java:6: error: method b in class Test cannot be applied to given types;
b(newList(type));
^
required: List<T>
found: CAP#1
reason: inference variable L has incompatible bounds
equality constraints: CAP#2
upper bounds: List<CAP#3>,List<?>
where T,L are type-variables:
T extends Object declared in method <T>b(List<T>)
L extends List<?> declared in method <L>newList(Class<L>)
where CAP#1,CAP#2,CAP#3 are fresh type-variables:
CAP#1 extends List<?> from capture of ? extends List<?>
CAP#2 extends List<?> from capture of ? extends List<?>
CAP#3 extends Object from capture of ?

一种解决方法是在本地分配一个变量:

import java.util.List;

public class Test {

static final void a(Class<? extends List<?>> type) {

// Workaround here
List<?> variable = newList(type);
b(variable);
}

static final <T> List<T> b(List<T> list) {
return list;
}

static final <L extends List<?>> L newList(Class<L> type) {
try {
return type.newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}

我知道类型推断在 Java 8 (e.g. due to JEP 101 "generalized target-type inference") 中发生了很大变化。那么,这是一个错误还是一个新的语言“功能”?

编辑:我也已将此问题作为 JI-9021550 报告给 Oracle,但以防万一这是 Java 8 中的“功能”,我也已向 Eclipse 报告了该问题:

最佳答案

免责声明 - 我对这个主题知之甚少,以下是我的非正式推理,试图证明 javac 的行为是正当的。


我们可以将问题简化为

<X extends List<?>> void a(Class<X> type) throws Exception
{
X instance = type.newInstance();
b(instance); // error
}

<T> List<T> b(List<T> list) { ... }

推断 T , 我们有约束

      X <: List<?>
X <: List<T>

本质上,这是无法解决的。例如,没有 T如果 X=List<?> 则存在.

不确定 Java7 如何推断这种情况。但我会说,javac8(和 IntelliJ)表现得“合理”。


现在,这个解决方法是如何工作的?

    List<?> instance = type.newInstance();
b(instance); // ok!

由于通配符捕获而起作用,它引入了更多类型信息,“缩小”了 instance 的类型

    instance is List<?>  =>  exist W, where instance is List<W>  =>  T=W

不幸的是,当 instanceX ,因此可以使用的类型信息较少。

可以想象,该语言也可以“改进”以对 X 进行通配符捕获:

    instance is X, X is List<?>  =>  exist W, where instance is List<W>

关于java - 推理变量具有不兼容的界限。 Java 8 编译器回归?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30622759/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com