[英]Generics propagation in Java
I have a Java code with quite tricky generics propagation scenario:我有一个 Java 代码具有相当棘手的 generics 传播场景:
public class Main {
public static void parent(Parent<String> parent) {}
public static void child(Child<String> parent) {}
public static <T> Parent<T> makeParent() {
return new Parent<>();
}
public static void main(String[] args) {
// this works
parent(makeParent());
// this works
Parent<String> objectParent = makeParent();
child(objectParent.child());
// this works
child(Main.<String>makeParent().child());
// this does not work
child(makeParent().child());
}
static class Parent<T> {
public Child<T> child() {
return new Child<>();
}
}
static class Child<T> {}
}
I am curious why and how this works parent(makeParent());
我很好奇为什么以及如何工作parent(makeParent());
? ? How replacement for T is inferred?如何推断 T 的替换?
And also why this does not work child(makeParent().child());
还有为什么这不起作用child(makeParent().child());
? ? As the same generic type is propagated.因为相同的泛型类型被传播。
The thing to remember about type inference in call chains is that the type inference is done as you move along the chain: if you have a().b()
:关于调用链中的类型推断要记住的是,类型推断是在您沿着链移动时完成的:如果您有a().b()
:
a()
first;首先为a()
运行类型推断;a().b()
然后为a().b()
推断出一个类型So:所以:
parent(makeParent())
: the type of makeParent()
is inferred according to what is compatible with the parameter of parent()
. parent(makeParent())
: makeParent()
() 的类型是根据与parent()
的参数兼容的情况来推断的。 Since that will only accept a Parent<String>
, that's the inferred type.由于那只会接受Parent<String>
,这就是推断的类型。
child(makeParent().child())
: the type of makeParent()
is inferred; child(makeParent().child())
:推断makeParent()
的类型; but there are no constraints on the type (it's not the parameter to the outer child
), so it's inferred to be Parent<Object>
;但是对类型没有限制(它不是外部child
的参数),因此推断为Parent<Object>
; then the type of makeParent().child()
is Child<Object>
, which isn't compatible with the parameter type of child
, hence the compiler error.那么makeParent().child()
的类型是Child<Object>
,它与child
的参数类型不兼容,因此编译器错误。
It's annoying that Java doesn't defer the type inference of makeParent()
until it has more information, namely the fact that makeParent().child()
has to be compatible with some particular type.令人讨厌的是 Java 没有推迟makeParent()
的类型推断,直到它有更多信息,即makeParent().child()
必须与某些特定类型兼容这一事实。
I suppose this is done to limit the complexity of the inference: I can imagine a situation where some obscenely complex set of type inference constraints could need to be solved.我想这样做是为了限制推理的复杂性:我可以想象需要解决一些极其复杂的类型推理约束集的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.