本文介紹了為什么Java泛型類型推斷在鏈?zhǔn)椒椒ㄕ{(diào)用中中斷?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
查看以下示例中泛型類型的類型推斷,我說不出為什么methodAutoTypeInference
工作得很好,但methodNotCompilable
(幾乎相同)無法編譯,為了管理它,編譯器需要其他技巧,如methodWorkaroundTypeHint
或methodWorkaroundTypeCast
。
methodNotCompilable
導(dǎo)致編譯器不確定表達(dá)式類型和方法結(jié)果類型是否兼容的問題是什么?
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幾乎覆蓋了相同的區(qū)域。只需注意Stuart Marks說:該編譯器可能會在未來的發(fā)行版中得到增強(qiáng)以涵蓋這種情況。盡管有lambdas
的情況,但這與您的情況沒有太大不同。這就是(目前)編譯器的工作方式。我們對此深信不疑。
您可以通過以下方式查看編譯器對return Stream.of("a").distinct();
的看法并決定使用哪種類型:
javac --debug=verboseResolution=all
這是一個未記錄在案的標(biāo)志。如果您使用該標(biāo)志進(jìn)行編譯,您將看到一些很大的輸出:
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
類型的解析是基于方法調(diào)用完成的;而不是整個調(diào)用鏈。順便說一句,如果是這樣的話,這會使編譯器的工作變得非常復(fù)雜。對于這樣一個簡單的鏈條來說,事情可能看起來微不足道,但當(dāng)有很多事情時,它就會變得非常、非常棘手和復(fù)雜。尤其是當(dāng)你發(fā)現(xiàn)non-denotable types
的時候,這會讓事情變得更加復(fù)雜。
這篇關(guān)于為什么Java泛型類型推斷在鏈?zhǔn)椒椒ㄕ{(diào)用中中斷?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,