考虑以下类别:
public class Foo extends Exception implements CharSequence { //...}
该类同时
Foo实现
Throwable和
CharSequence。因此,如果
E将其设置为该实例,则Java编译器将不知道调用哪个方法。
Java7 可能没有问题的 原因 是泛型的实现较少。如果您不提供
E自己的信息(例如
(Foo)bar()),则Java会退回其基本版本
E为
implements Exception,
E因此仅被视为的实例
Exception。
在 Java8中 , 类型推断
得到了改进,
E现在从调用的参数派生了的类型,
then()换句话说,编译器首先查找可能
then()需要的类型,问题在于它们都是有效的选择。因此,在这种情况下,它变得模棱两可。
概念证明 :
现在,我们将稍微修改您的代码,并显示如何解决歧义调用:
假设我们将代码修改为:
public class Main { public static void main(String... args){ then(bar()); // Compilation Error } public static <E extends Exception> E bar() { return null; } public static void then(CharSequence actual) { System.out.println("char"); }}
如果您在 Java8中 运行它, 那么
就不会有问题(它会打印
char),因为Java8只是假设存在此类
Foo(它为这两个类都派生了某种“内部”类型)。
在 Java7中 运行它 会 产生问题:
/MyClass.java:18: error: method then in class MyClass cannot be applied to given types; then(bar()); // Compilation Error ^ required: CharSequence found: Exception reason: actual argument Exception cannot be converted to CharSequence by method invocation conversion1 error
它进行了回退,
Exception找不到可以处理的类型。
如果您在运行原始代码 Java8 ,它将错误,因为暧昧通话,如果你在运行它 Java7 但是,它会使用
Throwable方法。
简而言之: 编译器旨在“猜测”E
Java8中的内容,而在Java7中则选择了最保守的类型。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)