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泛型类型推断在链式方法调用中中断?


- Eclipse 插件更新错误日志在哪里? 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01
- 如何使用WebFilter实现授权头检查 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01