Why does Java generics type inference break in chained method calls?(为什么Java泛型类型推断在链式方法调用中中断?)
问题描述
查看以下示例中泛型类型的类型推断,我说不出为什么methodAutoTypeInference工作得很好,但methodNotCompilable(几乎相同)无法编译,为了管理它,编译器需要其他技巧,如methodWorkaroundTypeHint或methodWorkaroundTypeCast。
methodNotCompilable导致编译器不确定表达式类型和方法结果类型是否兼容的问题是什么?
Stream<CharSequence> methodAutoTypeInference() {
return Stream.of("a");
}
Stream<CharSequence> methodNotCompilable() {
return Stream.of("a").distinct();
// incompatible types: java.util.stream.Stream<java.lang.String>
// cannot be converted to java.util.stream.Stream<java.lang.CharSequence>
}
Stream<CharSequence> methodWorkaroundTypeHint() {
return Stream.<CharSequence>of("a").distinct();
}
Stream<CharSequence> methodWorkaroundTypeCast() {
return Stream.of((CharSequence) "a").distinct();
}
推荐答案
This answer from JDK Developers themselves几乎覆盖了相同的区域。只需注意Stuart Marks说:该编译器可能会在未来的发行版中得到增强以涵盖这种情况。尽管有lambdas的情况,但这与您的情况没有太大不同。这就是(目前)编译器的工作方式。我们对此深信不疑。
您可以通过以下方式查看编译器对return Stream.of("a").distinct();的看法并决定使用哪种类型:
javac --debug=verboseResolution=all
这是一个未记录在案的标志。如果您使用该标志进行编译,您将看到一些很大的输出:
with actuals: no arguments
with type-args: no arguments
candidates:
#0 applicable method found: Object()
DeleteMe.java:60: Note: resolving method of in type Stream to candidate 1
return Stream.of("a").distinct();
^
phase: BASIC
with actuals: String
with type-args: no arguments
candidates:
#0 not applicable method found: <T#1>of(T#1...)
(cannot infer type-variable(s) T#1
(argument mismatch; String cannot be converted to T#1[]))
#1 applicable method found: <T#2>of(T#2)
(partially instantiated to: (String)Stream<String>)
where T#1,T#2 are type-variables:
T#1 extends Object declared in method <T#1>of(T#1...)
T#2 extends Object declared in method <T#2>of(T#2)
DeleteMe.java:60: Note: Deferred instantiation of method <T>of(T)
return Stream.of("a").distinct();
^
instantiated signature: (String)Stream<String>
target-type: <none>
where T is a type-variable:
T extends Object declared in method <T>of(T)
DeleteMe.java:60: Note: resolving method distinct in type Stream to candidate 0
return Stream.of("a").distinct();
^
phase: BASIC
with actuals: no arguments
with type-args: no arguments
candidates:
#0 applicable method found: distinct()
where T is a type-variable:
T extends Object declared in interface Stream
DeleteMe.java:60: error: incompatible types: Stream<String> cannot be converted to Stream<CharSequence>
return Stream.of("a").distinct();
^
1 error
我想最重要的部分是(partially instantiated to: (String)Stream<String>)
您可以看到,T类型的解析是基于方法调用完成的;而不是整个调用链。顺便说一句,如果是这样的话,这会使编译器的工作变得非常复杂。对于这样一个简单的链条来说,事情可能看起来微不足道,但当有很多事情时,它就会变得非常、非常棘手和复杂。尤其是当你发现non-denotable types的时候,这会让事情变得更加复杂。
这篇关于为什么Java泛型类型推断在链式方法调用中中断?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么Java泛型类型推断在链式方法调用中中断?
基础教程推荐
- 控制台应用程序中的 Java 键盘输入解析 2022-01-01
- 将 Windows 证书导入 Java 2022-01-01
- 在springboot中如何给mybatis加拦截器 2023-04-29
- 在java中使用xpath和selenium解析HTML表格数据 2022-01-01
- Maven:无效的目标版本:10 2022-01-01
- 将 double 转换为 Int,向下舍入 2022-01-01
- doFilter()是在servlet的工作完成之前还是之后执行的? 2022-01-01
- JPA惰性列表上的流 2022-01-01
- Java ECDSAwithSHA256 签名长度不一致 2022-01-01
- 如何在相机中应用自定义滤镜 [Surfaceview 预览]. 2022-01-01
