Эта проблема возникает конкретно в Android (но не ограничивается).Таким образом, мы создаем 2 оболочки, но назначение объекта выполняется внутри (если бы я создал оболочку wrongWrapper
, используя new AWrapper<>((B1) findObjectStupid(false));
, это дало бы ClassCastException
сразу, а не позже)
class A {}
class B1 extends A {}
class B2 extends A {}
class AWrapper<T extends A> {
T a;
AWrapper(T a) {
this.a = a;
}
AWrapper(boolean b) {
this((T) findObjectStupid(b)); //this throws a ClassCastException only if findObjectStupid(b) is not an A class
}
public T getA() {
return a;
}
}
<T extends A> T findObjectStupid(boolean b) { /in android this method mimics the findViewById(int id)
if (b) {
return (T) new B1();
} else {
return (T) new B2();
}
}
void main() {
AWrapper<B1> rightWrapper = new AWrapper<>(true);
AWrapper<?> dontCareWrapper = new AWrapper<>(true);
AWrapper<B1> wrongWrapper = new AWrapper<>(false); //should give ClassCastException now, but doesn't
//AWrapper<B1> wrongWrapper = new AWrapper<>((B1) findObjectStupid(false)); //this way ClassCastException is thrown immediately
B1 rightObject = rightWrapper.getA();
A dontCareObject = dontCareWrapper.getA(); // we know we can cast it to B1 and it would work
B1 wrongObject = wrongWrapper.getA(); //gives ClassCastException now, not good!
}
Очевидно, чтоОболочка разработана, чтобы иметь методы, которые используют Объект как A, единственный тип времени, в котором действительно необходим тип T, - это когда вызывается getA()
, что делает эту обертку проблематичной, если рассматриваемый программист забывает сегодня вызвать этот конкретный метод, и ошибка может остатьсяскрытый в течение долгого времени, пока он действительно не понадобится.
Как можно изменить вышеупомянутую оболочку, чтобы она создавала исключение ClassCastException при создании, а не при вызове getA()
?