这个深奥的泛型错误是编译器错误还是新限制? (推断类型不符合上限)
Posted
技术标签:
【中文标题】这个深奥的泛型错误是编译器错误还是新限制? (推断类型不符合上限)【英文标题】:Is this esoteric generics error a compiler bug or a new restriction? (inferred type does not conform to upper bounds) 【发布时间】:2015-07-09 12:26:21 【问题描述】:我从 Java 8u5 更新到 8u45,一些以前工作的代码不再编译。问题是,发生这种情况的一半时间是故意更改,所以我无法确定这是否是错误。
(我还测试到 u25,每个版本都与 u45 做同样的事情。)
但本质上,它与一个方法的多个返回点有关。例如:
import java.sql.Connection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class CompilerIssue
public Set<String> test(int value)
return perform(connection ->
if (value % 2 == 0)
return Collections.<String>emptySet();
else
return new HashSet<>(10);
);
<V> V perform(BusinessLogic<V> logic)
// would usually get a connection
return null;
interface BusinessLogic<V>
V execute(Connection connection) throws Exception;
javac 给出:
Error:(12, 23) java: incompatible types: inferred type does not conform to upper bound(s)
inferred: java.util.Set<? extends java.lang.Object>
upper bound(s): java.util.Set<java.lang.String>,java.lang.Object
IDEA,像往常一样,看不出任何问题。
我已经知道解决方法 - 将 HashSet<>
替换为 HashSet<String>
。但是我们在代码中普遍使用了这种结构,所以在我花时间彻底改变它之前,我想知道:这是一个错误,还是旧的行为是错误?
(如果是一个错误,那么我必须向 Oracle 报告一个错误。如果它是一个特性,那么我必须向 IDEA 报告一个错误,认为它没问题。)
【问题讨论】:
我也希望Collections.emptySet()
能够工作,但它会导致同样的错误。
@xehpuk 是的,如果使用 Collections.emptySet() 和 new HashSet据我所知,这是一个错误并且来自 Oracle,它没有从目标类型(句子 return 期望返回的类型)正确推断类型,而是以某种方式比较两个 return 句子的上限:(return Collections.<String>emptySet();
和 return new HashSet<>(10);
)。
在第二个 return 语句中,new HashSet<>(10)
的上限将是 Object
,但类型可以从返回类型推断为确实是 <String>
。尝试注释掉第一个 return 语句并返回 null 并编译:
public class CompilerIssue
public Set<String> test(int value)
return perform(connection ->
if (value % 2 == 0)
return null; // COMMENTED OUT FOR TESTING PURPOSES Collections.<String>emptySet();
else
return new HashSet<>(10);
);
<V> V perform(BusinessLogic<V> logic)
// would usually get a connection
return null;
interface BusinessLogic<V>
V execute(Connection connection) throws Exception;
这会编译,它会正确推断出HashSet<>(10)
的正确值类型应该是String
。
【讨论】:
以上是关于这个深奥的泛型错误是编译器错误还是新限制? (推断类型不符合上限)的主要内容,如果未能解决你的问题,请参考以下文章