-Классы проекта-
Класс A:
public class A {
public static void main(String[] args) {
D d = new D();
B.set(d);
d.add(new H()); //$ (correct error)
B.get().add(new H()); //! (no error)
}
}
Класс B:
public class B {
protected static C c;
public static C get() {
return B.c;
}
public static void set(C c)
B.c = c;
}
Класс C:
public abstract class C<T> {
protected ArrayList<T> array = new ArrayList<T>();
public void add(T element) {
this.array.add(element);
}
}
Класс D:
public class D extends C<G> {
//
}
Класс E:
public class E extends C<H> {
//
}
Класс F:
public abstract class F<T> {
//
}
Класс G:
public class G extends F<X> {
//
}
Класс H:
public class H extends F<Y> {
//
}
- класс ролей-
A
- это основной класс B
- это класс, в котором хранится ссылка на объект C
- это обобщенный c класс, который определяет массив объектов D
& E
extension C
с различными типами G
& H
расширение F
с различными типами
-Logi c Issue-
В A.main()
, //!
представляет, где находится проблема, и //$
представляет желаемое поведение. Поскольку B.get()
возвращает абстрактный тип C
, можно добавить недопустимый элемент в array
(в этом примере добавление H
, когда только G
допустимо из-за расширения D
C
).
Тип возвращаемого объекта из B.get()
неизвестен в программе (поскольку B.c
может представлять объект типа D
или типа E
), поэтому идеально подходит модификация B
для проверки типа c
и его возврата или автоматического приведения при вызове B.get()
, если это возможно.
-Вопросы редактирования-
Для уточнение, приведение с ((D) B.get()).add(new H());
бесполезно, так как дочерний тип, который содержит B. c, неизвестен. Если возможно сделать что-то похожее на ((B.get().getClass()) B.get()).add(new H())
, это было бы полезно. Решение, которое я выбрал бы, было бы предпочтительно изменением или в методе B.get()
, а не в основном методе, если это возможно.
Для дальнейшего разъяснения, результат решения этой проблемы предполагается приводить к ошибке , чтобы предотвратить нежелательное добавление недопустимых типов в массивы при ссылке из B.get()
(//!
обозначает, где не возникает ошибка, а //$
обозначает, где возникает ошибка , как и должно быть ). Я открыт для переписывания того, как сохранять ссылки на экземпляры D
и E
в B
, если можно сделать динамический c способ ссылки на тип C
(тип D
или введите E
) можно сделать.