【发布时间】:2015-11-23 14:52:56
【问题描述】:
我有以下通用测试类:
public class BrokenGenerics<T> {
private T[] genericTypeArray;
public BrokenGenerics(T... initArray) {
genericTypeArray = initArray;
}
public void setArray(T[] newArray) {
genericTypeArray = newArray;
}
public T get(int idx) {
return genericTypeArray[idx];
}
public Class getType() {
return genericTypeArray.getClass().getComponentType();
}
public static boolean breakThis(BrokenGenerics any) {
any.setArray(new B[]{new B(2)});
return false;
}
public static void main(String[] args) {
BrokenGenerics<A> aBreaker = new BrokenGenerics<A>(new A("1"));
System.out.println(aBreaker.get(0));
System.out.println(aBreaker.getType());
breakThis(aBreaker);
System.out.println(aBreaker.get(0));
System.out.println(aBreaker.getType());
}
private static class A {
public String val;
public A(String init) {
val = init;
}
@Override
public String toString() {
return "A value: " + val;
}
}
private static class B {
public int val;
public B(int init) {
val = init;
}
@Override
public String toString() {
return "B value: " + val;
}
}
}
当我运行它时,我得到了这个输出,并且没有错误:
A value: 1
class BrokenGenerics$A
B value: 2
class BrokenGenerics$B
现在,我明白为什么会编译了;它在编译时无法知道 breakThis 正在传递一个错误类型的泛型。但是,一旦它运行any.setArray(new B[]{new B(2)}); 行,它不应该抛出一个ClassCastException(注意它不是!你自己试试吧!)因为我试图将B[] 传递给一个方法期望A[]?然后,为什么它允许我get() 回B?
【问题讨论】:
-
我确定编译器会发出警告。它不能做太多其他事情,因为
T在运行时是Object。 -
@Kayaman 编译器也不会发出任何警告。我的代码被绿了!在编译或运行时没有警告或错误。
-
@BenC.R.Leggiero 您不可能没有收到任何警告。至少,您应该收到
public static boolean breakThis(BrokenGenerics any) {的原始类型警告。 -
@Powerlord 你有没有把它放到你的IDE中并收到警告?也许我的 IDE 只是没有向我显示它们。
-
好的。有道理。我现在也不相信这种双重性。如果您将不同类型的元素添加 在一起,您会得到
ClassCastException,但在这种情况下,您将完全破坏数组。