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:带有char数组的println给出乱码 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- 降序排序:Java Map 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01