[英]Generics <? super> wildcard not working in java 1.8 with method reference or lambda
package com.test.lambda;
import java.util.function.Supplier;
class Document {
void printAuthor() {
System.out.println("Document-Author");
}
}
class RFP extends Document {
@Override
void printAuthor() {
System.out.println("RFP-Author");
}
}
public class TestLambda1 {
public static void function21() {
Supplier<Document> s1 = Document::new; // working
Supplier<Document> s2 = RFP::new; // (1)
Supplier<? extends Document> s3 = Document::new; // working
Supplier<? extends Document> s4 = RFP::new; // working
Supplier<? super Document> s5 = Document::new; // working
Supplier<? super Document> s6 = RFP::new; // (2)
Supplier<? super RFP> s7 = Document::new; // (3)
Supplier<? super RFP> s8 = RFP::new; // working
}
public static void main(String[] args) throws Exception {
function21();
}
}
(1) (2) & (3) 中的問題是,它應該像 java 1.7 (1) 一樣工作:它應該給出錯誤,因為應該只接受文檔類型。 (2):它應該給出錯誤,因為應該只接受超類型的 Document。 (3):它應該作為RFP的super可以持有文件object。 <? 之間的區別 超級 T> 和 <? 在 Java 中擴展 T>
在 Java 1.7 和 Java 1.7 中堅持“它應該像 java 1.7 一樣工作”是很奇怪的。 Java 7 根本沒有方法引用。
當你寫一個像
Supplier<Document> s2 = RFP::new;
您必須區分變量的類型、function 的類型和實際實現。 您可以輕松編寫等效的
Supplier<Document> s2 = new Supplier<Document>() {
public Document get() {
return new RFP();
}
}; // (1)
由於協變返回類型,您還可以編寫
Supplier<Document> s2 = new Supplier<Document>() {
public RFP get() {
return new RFP();
}
}; // (1)
所以變量的類型匹配 function 的類型,而實現返回一個更具體類型的實例。
當你寫
Supplier<? extends Document> s3 = Document::new; // working
Supplier<? extends Document> s4 = RFP::new; // working
Supplier<? super Document> s5 = Document::new; // working
Supplier<? super Document> s6 = RFP::new; // (2)
function 的類型會有所不同。 你不能寫new Supplier<? extends Document>() { … }
new Supplier<? extends Document>() { … }
也不是new Supplier<? super Document>() { … }
new Supplier<? super Document>() { … }
所以編譯器會推斷出一個可以實例化的類型,它只是沒有? extends
? extends
或? super
? super
。 所以它相當於
Supplier<? extends Document> s3 = (Supplier<Document>)Document::new; // working
Supplier<? extends Document> s4 = (Supplier<Document>)RFP::new; // working
Supplier<? super Document> s5 = (Supplier<Document>)Document::new; // working
Supplier<? super Document> s6 = (Supplier<Document>)RFP::new; // (2) just like (1)
它們是有效的實例化(如在第一個塊中),然后是合法的賦值。
問題與
Supplier<? super RFP> s7 = Document::new; // (3)
正是在上面描述的類型推斷邏輯中。 類型推斷將使用不帶? super
? super
和(Supplier<RFP>)Document::new
無效。 所以在這里,我們必須提供一個顯式類型來使其有效:
Supplier<? super RFP> s7 = (Supplier<Document>)Document::new; // (3)
它遵循與第二塊相同的模式。
你不能實現一個Supplier<? super RFP>
Supplier<? super RFP>
. 您可以實現像Supplier<Document>
這樣可分配給Supplier<? super RFP>
Supplier<? super RFP>
. 當目標類型有通配符時,去掉通配符的策略通常會有所幫助,但有時不會。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.