有人可以告诉我为什么我没有得到ClassCastException这个片段?我非常感兴趣的是它为什么不像我期望的那样工作.在这一点上我不在乎这是不是很糟糕的设计.
public class Test {
static class Parent {
@Override
public String toString() { return "parent"; }
}
static class ChildA extends Parent {
@Override
public String toString() { return "child A"; }
}
static class ChildB extends Parent {
@Override
public String toString() { return "child B"; }
}
public <C extends Parent> C get() {
return (C) new ChildA();
}
public static void main(String[] args) {
Test test = new Test();
// should throw ClassCastException...
System.out.println(test.<ChildB>get()); …Run Code Online (Sandbox Code Playgroud) 我正在阅读有关varargs堆污染的内容,我并不真正了解varargs或non-reifiable类型将如何解决那些在没有通用性的情况下尚未存在的问题.的确,我可以很容易地取代
public static void faultyMethod(List<String>... l) {
Object[] objectArray = l; // Valid
objectArray[0] = Arrays.asList(42);
String s = l[0].get(0); // ClassCastException thrown here
}
Run Code Online (Sandbox Code Playgroud)
同
public static void faultyMethod(String... l) {
Object[] objectArray = l; // Valid
objectArray[0] = 42; // ArrayStoreException thrown here
String s = l[0];
}
Run Code Online (Sandbox Code Playgroud)
第二个只是使用数组的协方差,这实际上是问题所在.(即使List<String>是可以恢复的,我想它仍然是子类,Object我仍然可以将任何对象分配给数组.)当然我可以看到两者之间有一点差别,但是这个代码是错误的,无论是是否使用泛型.
它们对堆污染的意义是什么(它让我考虑内存使用情况,但他们谈到的唯一问题是潜在的类型不安全),它与使用数组协方差的任何类型违规有何不同?
这太神奇了!看看这个简单的代码:
public class ArrayOFMagic<T> {
protected T[] array;
protected int showMeYouRLength() {
return array.length;
}
ArrayOFMagic() {
array = (T[]) new Object[10];
}
protected void set(T value, int index) {
array[index] = value;
}
public static void main(String[] args) {
ArrayOFMagic<Integer> arrayOFMagic = new ArrayOFMagic<Integer>();
System.out.println(arrayOFMagic.showMeYouRLength());
System.out.println("MAGIC INCOMING");
System.out.println(arrayOFMagic.array.length);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
10
MAGIC INCOMING
线程"main"中的异常java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为[Ljava.lang.Integer; 在ArrayOFMagic.main(ArrayOFMagic.java:25)
我两次调用array.length.一次通过方法,直接一次.它在使用方法时继续,并在直接调用时抛出异常.Oo有人解释?
编辑:只是为了澄清:当没有直接调用时,类工作正常.你可以在数组元素和所有..上设置setter/getter!
Class<? extends MyClass> cls = (Class<? extends MyClass>) Class.forName(className);
someMethod(cls); // someMethod expects a Class<? extends MyClass>
Run Code Online (Sandbox Code Playgroud)
上面的语句给出了一个警告"类型安全:未选中强制转换Class<capture#5-of ?>为Class<? extends MyClass>".
Class<?> cls0 = Class.forName(className);
if (cls0 instanceof Class<? extends MyClass>) {
Class<? extends MyClass> cls = (Class<? extends MyClass>)cls0;
someMethod(cls);
}
Run Code Online (Sandbox Code Playgroud)
这次我得到一个错误,因为类型擦除...
Class<?> cls0 = Class.forName(className);
if (MyClass.class.isAssignableFrom(cls0)) {
Class<? extends MyClass> cls = (Class<? extends MyClass>)cls0;
someMethod(cls);
}
Run Code Online (Sandbox Code Playgroud)
这次我知道演员阵容是安全的,但是编译器没有,并且仍然发出警告.(如果你问我,这里的编译器有点厚.)
有没有办法避免这种警告(SuppressWarnings除外)?