diz*_*iaq 6 java generics type-inference compilation
在下面的示例中查看泛型类型的类型推断,我不能说为什么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();
}
Run Code Online (Sandbox Code Playgroud)
JDK 开发人员自己的回答涵盖了相同的领域。请注意 Stuart Marks 说:“编译器可能会得到增强,以在未来的版本中涵盖这种情况”。虽然周围也有这种情况lambdas,但这与您的情况并没有太大不同。这就是编译器(目前)的工作方式。我们被这个问题“困住”了。
您可以通过以下方式查看编译器如何思考return Stream.of("a").distinct();并决定使用什么类型的解决方案:
javac --debug=verboseResolution=all
Run Code Online (Sandbox Code Playgroud)
这是一个未记录的标志。如果使用该标志进行编译,您将看到一些大输出:
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
Run Code Online (Sandbox Code Playgroud)
我想最重要的部分是:(partially instantiated to: (String)Stream<String>)
可以看到,解析是什么类型T,是根据方法调用来做的;不是整个调用链的。顺便说一句,如果会的话,这将使编译器的工作变得相当复杂。对于像这样的简单链条,事情可能看起来微不足道,但当有很多事情时,事情就会变得更加棘手和复杂。尤其是当你发现 时non-denotable types,这会让事情变得更加复杂。
| 归档时间: |
|
| 查看次数: |
154 次 |
| 最近记录: |