[英]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();
}
}
Problem in (1) (2) & (3) is that, it should work as java 1.7 (1): it should give error as only Document type should be accepted. (1) (2) & (3) 中的问题是,它应该像 java 1.7 (1) 一样工作:它应该给出错误,因为应该只接受文档类型。 (2): it should give error as only super type of Document should be accepted. (2):它应该给出错误,因为应该只接受超类型的 Document。 (3): it should be working as super of RFP can hold Document object. (3):它应该作为RFP的super可以持有文件object。 Difference between <? <? 之间的区别super T> and <? 超级 T> 和 <? extends T> in Java 在 Java 中扩展 T>
It's weird to insist on “it should work as java 1.7”, when in Java 1.7 resp.在 Java 1.7 和 Java 1.7 中坚持“它应该像 java 1.7 一样工作”是很奇怪的。 Java 7 there were no method references at all. Java 7 根本没有方法引用。
When you write a statement like当你写一个像
Supplier<Document> s2 = RFP::new;
You have to make a distinction between the type of the variable, the type of the function, and the actual implementation.您必须区分变量的类型、function 的类型和实际实现。 You can easily write the equivalent您可以轻松编写等效的
Supplier<Document> s2 = new Supplier<Document>() {
public Document get() {
return new RFP();
}
}; // (1)
due to covariant return types, you can also write由于协变返回类型,您还可以编写
Supplier<Document> s2 = new Supplier<Document>() {
public RFP get() {
return new RFP();
}
}; // (1)
So the type of the variable matches the type of the function, whereas the implementation returns an instance of a more specific type.所以变量的类型匹配 function 的类型,而实现返回一个更具体类型的实例。
When you write当你写
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)
the type of the function will differ. function 的类型会有所不同。 You can not write new Supplier<? extends Document>() { … }
你不能写new Supplier<? extends Document>() { … }
new Supplier<? extends Document>() { … }
nor new Supplier<? super Document>() { … }
new Supplier<? extends Document>() { … }
也不是new Supplier<? super Document>() { … }
new Supplier<? super Document>() { … }
and so the compiler will infer a type that can be instantiated, which simply is the target type type without ? extends
new Supplier<? super Document>() { … }
所以编译器会推断出一个可以实例化的类型,它只是没有? extends
? extends
or ? super
? extends
或? super
? super
. ? super
。 So it's equivalent to所以它相当于
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)
which are valid instantiations (like in the first block), followed by legal assignments.它们是有效的实例化(如在第一个块中),然后是合法的赋值。
The problem with问题与
Supplier<? super RFP> s7 = Document::new; // (3)
lies exactly in the type inference logic described above.正是在上面描述的类型推断逻辑中。 The type inference will use the type without ? super
类型推断将使用不带? super
? super
, and (Supplier<RFP>)Document::new
is not valid. ? super
和(Supplier<RFP>)Document::new
无效。 So here, we have to provide an explicit type to make it valid:所以在这里,我们必须提供一个显式类型来使其有效:
Supplier<? super RFP> s7 = (Supplier<Document>)Document::new; // (3)
which follows the same pattern as the second block.它遵循与第二块相同的模式。
You can not implement a Supplier<? super RFP>
你不能实现一个Supplier<? super RFP>
Supplier<? super RFP>
. Supplier<? super RFP>
. You can implement a supplier like Supplier<Document>
which is assignable to Supplier<? super RFP>
您可以实现像Supplier<Document>
这样可分配给Supplier<? super RFP>
Supplier<? super RFP>
. Supplier<? super RFP>
. When the target type has wildcards, the strategy to just strip off the wildcards often helps but sometimes doesn't.当目标类型有通配符时,去掉通配符的策略通常会有所帮助,但有时不会。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.