У меня есть простой общий класс списка. Я пытаюсь добиться этого: учитывая экземпляр списка, о котором мы знаем только, что он содержит экземпляры определенного подкласса класса и задан экземпляр этого класса, добавьте этот экземпляр в список, если он является экземпляром содержащегося (подкласса), иначе выведите исключение (например, ClassCastException). Я попытался следующие:Как обеспечить корректность параметризованного типа во время выполнения на Java?
class MyList<T>
{
private Class<T> genericClass;
private List<T> list = new ArrayList<>();
public MyList(Class<T> genericClass)
{
this.genericClass = genericClass;
}
public void add(T elem)
{
list.add(elem);
}
//...
public Class<T> getGenericParamClass()
{
return genericClass;
}
}
class A{}
class B extends A{}
class C extends A{}
class Program
{
public static void main(String... args)
{
MyList<B> list1 = new MyList<>(B.class);
MyList<C> list2 = new MyList<>(C.class);
MyList<? extends A> ls = checkStuff() ? list1 : list2;
ls.add(ls.getGenericParamClass().cast(lotsOfStuff())); //ERROR ?!!
}
static boolean checkStuff()
{
Random random = new Random();
return random.nextBoolean();
}
static A lotsOfStuff()
{
return new B();
}
}
Я думал, что данный объект класса, тип которого параметр совпадает с типом параметра метода, я смог бы бросить что-то, используя прежний, чтобы быть в состоянии пройти это последнему. Увы, кажется, я не могу: я получаю ошибку времени компиляции!
я мог бросить дженерики из окна, идут полным бесконтрольно и просто сказать:
A val = lotsOfStuff();
if (myList.getGenericParamClass().isInstance(val))
ls.add(val)
else
throw new SomeException();
Но, что, вероятно, создаст больше проблем, чем решить, а также это было бы действительно ошибка меня.
Я пропустил что-то здесь, или это просто невозможно, как я думал об этом?
Edit: Я полностью понимаю, а почему-то, как это не может работать:
List<? extends Number> abc=new ArrayList<Integer>(); abc.add(new Integer(10));
Но на мой взгляд, следующие транзитивности: тип параметра оных() Is-The-Same - как параметр типа MyList Is-The-Same - как параметр типа класса, возвращаемого getGenericParamClass() Is-The-Same-как возвращаемый тип метода cast() этого класса. Я (как человек) может знать, что эти неизвестные типы одинаковы, потому что я получаю их от одного и того же объекта.
Есть ли ошибка в моей логике или это ограничение Java?
не буду [ 'Коллекция. checkedList'] (http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#checkedList (java.util.List,% 20java.lang.Class)) сделать это из коробка? –
Попробуйте этот простой код 'List extends Number> abc = new ArrayList(); abc.add (новый Integer (10)); 'и затем прочитайте его здесь [Когда для генерирования Java требуется extends T> вместо и есть ли недостатки переключения?] (http://stackoverflow.com/questions/897935/when -do-ява-генерики-требует, распространяется трет-вместо-о-т-и--там любой вниз) –
Braj