- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我从 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 报告一个错误,认为它是可以的。)
最佳答案
据我所知,它是一个错误并且来自 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
.
关于java - 这个深奥的泛型错误是编译器错误还是新限制? (推断类型不符合上限),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29956936/
我是一名优秀的程序员,十分优秀!