为什么编译器无法推断 Java 中内部 class 的泛型类型?
Why compiler cannot infer generic types of the inner class in Java?
class A<T>
{
class InnerA<U>
{}
}
public class Main
{
public static void main(String[] args)
{
A<Integer>.InnerA<String> var = new A<>().new InnerA<>();
}
}
编译上述代码片段时,会导致编译时错误,提示“不兼容的类型:无法推断 A.InnerA<>
的类型参数。在我看来,编译器应该能够推断类型成为 InnerA<String>
.
为什么不能这样做?如果有人可以解释它是如何在幕后工作的,那将会很有帮助。
编译器错误消息具有误导性。
编译器只能从赋值的左侧推断表达式的类型,前提是表达式是其结果实际被赋值的表达式。在您的示例中,new A<>()
未分配,而仅用于内部 class¹ 的合格实例化。由于 new A<>()
没有赋值上下文,编译器推断 new A<Object>()
.
对于 .new InnerA<>()
,有一个赋值上下文,编译器尝试使用赋值的左侧来推断结果类型但失败了,因为 A
的类型已经不兼容。在缩短的编译器消息中,无法推断 InnerA
的类型是可见的,但不是 A
.
的类型参数不匹配的原因
长错误信息看起来像
Main.java:11: error: incompatible types: cannot infer type arguments for A.InnerA<>
A<Integer>.InnerA<String> var = new A<>().new InnerA<>();
^
reason: no instance(s) of type variable(s) U exist
so that A<Object>.InnerA<U> conforms to A<Integer>.InnerA<String>
where U is a type-variable:
U extends Object declared in class A.InnerA
所以问题仍然被报告为“找不到 U
的类型”,但我们也可以看到更深层次的原因是没有 U
可以解决 A<T>
.
类型不匹配的问题
我们还可以通过将行更改为
来证明实际原因
A<Integer>.InnerA<String> var = new A<>().new InnerA<String>();
为 InnerA
提供正确的类型,现在得到
incompatible types:
A<Object>.InnerA<String> cannot be converted to A<Integer>.InnerA<String>
或将行更改为
A<Integer>.InnerA<String> var = new A<Integer>().new InnerA<>();
这将解决问题,因为现在 A
具有正确的类型,并且可以从左侧推断出 InnerA
的类型。
¹ 如果您 genericMethod1().method2()
也会出现同样的问题
class A<T>
{
class InnerA<U>
{}
}
public class Main
{
public static void main(String[] args)
{
A<Integer>.InnerA<String> var = new A<>().new InnerA<>();
}
}
编译上述代码片段时,会导致编译时错误,提示“不兼容的类型:无法推断 A.InnerA<>
的类型参数。在我看来,编译器应该能够推断类型成为 InnerA<String>
.
为什么不能这样做?如果有人可以解释它是如何在幕后工作的,那将会很有帮助。
编译器错误消息具有误导性。
编译器只能从赋值的左侧推断表达式的类型,前提是表达式是其结果实际被赋值的表达式。在您的示例中,new A<>()
未分配,而仅用于内部 class¹ 的合格实例化。由于 new A<>()
没有赋值上下文,编译器推断 new A<Object>()
.
对于 .new InnerA<>()
,有一个赋值上下文,编译器尝试使用赋值的左侧来推断结果类型但失败了,因为 A
的类型已经不兼容。在缩短的编译器消息中,无法推断 InnerA
的类型是可见的,但不是 A
.
长错误信息看起来像
Main.java:11: error: incompatible types: cannot infer type arguments for A.InnerA<>
A<Integer>.InnerA<String> var = new A<>().new InnerA<>();
^
reason: no instance(s) of type variable(s) U exist
so that A<Object>.InnerA<U> conforms to A<Integer>.InnerA<String>
where U is a type-variable:
U extends Object declared in class A.InnerA
所以问题仍然被报告为“找不到 U
的类型”,但我们也可以看到更深层次的原因是没有 U
可以解决 A<T>
.
我们还可以通过将行更改为
来证明实际原因A<Integer>.InnerA<String> var = new A<>().new InnerA<String>();
为 InnerA
提供正确的类型,现在得到
incompatible types:
A<Object>.InnerA<String> cannot be converted to A<Integer>.InnerA<String>
或将行更改为
A<Integer>.InnerA<String> var = new A<Integer>().new InnerA<>();
这将解决问题,因为现在 A
具有正确的类型,并且可以从左侧推断出 InnerA
的类型。
¹ 如果您 genericMethod1().method2()