Vic*_*tor 5 java generics type-inference generic-programming inferred-type
在这段代码中,T可以是A,B,C或D,但Eclipse显示它是D.
static class A { }
static class B extends A { }
static class C extends B { }
static class D extends C { }
static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (T t : src)
dst.add(t);
}
public static void main(String[] args) {
List<A> dst = new ArrayList<>();
List<D> src = new ArrayList<>();
copy(dst, src); // Eclipse shows T is D
}
Run Code Online (Sandbox Code Playgroud)
是否有关于类型推断如何完成以及为什么选择D的规则?
是否有关于类型推断如何完成的规则
为什么选择D?
我认为以下规则对此负责:
如果绑定集不包含对于所有i(1≤i≤n)的形式G <...,αi,...> = capture(G <...>)的边界,则候选实例化Ti为每个αi定义:
如果αi具有一个或多个适当的下界,L1,...,Lk,则Ti = lub(L1,...,Lk)(§4.10.4).
否则,如果绑定集包含抛出αi,并且αi的适当上限最多为Exception,Throwable和Object,则Ti = RuntimeException.
否则,αi具有适当的上限U1,...,Uk,Ti = glb(U1,...,Uk)(§5.1.10).
边界α1= T1,...,αn= Tn与当前边界集合并入.
如果结果不包含绑定的false,则结果变为新的绑定集,并且通过选择要实例化的新变量集(如果需要)来进行解析,如上所述.
简单来说,在尝试类型参数的可能值时,编译器首先尝试下限,并在适合时使用该值.
在我们的例子中,设置约束说D extends T and D extends A,所以下界T是D,所以D是第一候选替换.
编译器D通过假设T = D,这简化了设置的约束来验证是否适合D extends D and D extends A,两者都已知为真.
因此,编译器使用D.
| 归档时间: |
|
| 查看次数: |
125 次 |
| 最近记录: |