Java泛型狂野用法和对象



我正在研究《Java编程导论》中的实践问题,包括数据结构,第十一版,Y.Daniel Liang。

19.24  Which of the following can be used to replace YYYYYYYY in the following code?
public class WildCardDemo3 {
public static void main(String[] args) {
GenericStack<String> stack1 = new GenericStack<>();
GenericStack<Object> stack2 = new GenericStack<>();
stack2.push("Java");
stack2.push(2);
stack1.push("Sun");
add(stack1, stack2);
WildCardDemo2.print(stack2);
}
public static <T> void YYYYYYYY {
while (!stack1.isEmpty())
stack2.push(stack1.pop());
}
}
A. add(GenericStack<T> stack1, GenericStack<T> stack2)
B. add(GenericStack<? extends T> stack1, GenericStack<T> stack2)
C. add(GenericStack<T> stack1, GenericStack<? super T> stack2)
D. add(GenericStack<T> stack1, GenericStack<Object> stack2)

答案D也起作用,这有道理吗。我知道stack2是一种对象类型,但我认为它应该定义为与类型参数相关。对不起,这是个愚蠢的问题。

选项A不编译(在add(stack1, stack2)行(,因为在这种情况下,编译器要求两个堆栈具有完全相同的泛型类型。实际上,我们有StringObject,它们并不相同。

选项B编译。实际上它变成了:

<Object> void add(GenericStack</*String*/ ? extends Object> stack1, GenericStack<Object> stack2)

CCD_ 4扩展了CCD_。满足通配符限制。

选项C编译。实际上它变成了:

<String> void add(GenericStack<String> stack1, GenericStack</*Object*/? super String> stack2)

Object是Java中包括String在内的所有类的超类。满足通配符限制。

选项D编译。实际上它变成了:

<String> void add(GenericStack<String> stack1, GenericStack<Object> stack2)

Object类比String类宽。这就是为什么GenericStack<Object> stack2可以包含来自GenericStack<String> stack1的String值。

你是对的,D能起作用。唯一不起作用的是A。你可以通过编写代码并运行它来自己检查它

最新更新