Странно настаивать на том, что «это должно работать как Java 1.7», когда в Java 1.7 соотв.В Java 7 вообще не было ссылок на методы.
Когда вы пишете оператор типа
Supplier<Document> s2 = RFP::new;
Вы должны различать тип переменной и тип функции,и фактическая реализация.Вы можете легко написать эквивалент
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)
Таким образом, тип переменной соответствует типу функции, тогда как реализациявозвращает экземпляр более определенного типа.
Когда вы пишете
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)
, тип функции будет отличаться.Вы не можете писать new Supplier<? extends Document>() { … }
или new Supplier<? super Document>() { … }
, и поэтому компилятор выведет тип, который может быть создан, который просто является типом целевого типа без ? extends
или ? 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
, а (Supplier<RFP>)Document::new
недопустим.Поэтому здесь мы должны предоставить явный тип, чтобы сделать его действительным:
Supplier<? super RFP> s7 = (Supplier<Document>)Document::new; // (3)
, который следует той же схеме, что и второй блок.
Вы не можете реализовать Supplier<? super RFP>
.Вы можете реализовать такого поставщика, как Supplier<Document>
, который может быть назначен на Supplier<? super RFP>
.Когда у целевого типа есть символы подстановки, стратегия простого удаления символов подстановки часто помогает, но иногда нет.