Как уже упоминалось, стирание типов общих типов не позволяет этого. Но вы можете достичь того, что вы хотите, как это:
public class BaseClass {
public BaseClass(int theParam) {
// ...whatever...
}
public BaseClass() {
}
}
public class DerivedType extends BaseClass {
}
А теперь метод doIt () получает аргумент класса для справки:
public <D extends BaseClass> boolean doIt (ArrayList<D> target, Class<D> c)
{
try {
D newElem = c.getDeclaredConstructor(int.class).newInstance(5);
} catch (Exception e) {}
// ...other code does not matter...
return true ;
}
И вы должны назвать это так:
ArrayList<DerivedType> testList = new ArrayList<DerivedType>();
testList.add(new DerivedType());
testList.add(new DerivedType());
doIt(testList, DerivedType.class);
Надеюсь, это поможет:)
Обратите внимание, что кто-то может захотеть быть хакером, избавиться от параметра класса и попробовать это:
public static <D extends BaseClass> boolean doIt (ArrayList<D> target)
{
try {
D newElem1 = ((Class<D>) ((ParameterizedType) target.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getDeclaredConstructor(int.class).newInstance(5);
} catch (Exception e) { e.printStackTrace();}
return true ;
}
}
На самом деле я так и думал перед вторым редактированием. исключение, как вы упомянули (я не видел его из-за пропущенного оператора catch). Короче говоря, система времени исполнения Java не хранит параметризованные типы (в пользу обратной совместимости; поэтому это может измениться в будущем).
Итак, похоже, что это невозможно без «прикосновения» к какому-либо классу.
Однако, кроме упомянутых методов, я могу вспомнить еще две вещи . Во-первых, если и BaseClass, и класс DerivedType 'D' реализуют метод clone (), вы можете получить клон объекта из массива и затем использовать его:
D o = target.get(0);
D oNew = (D)((BaseClass)o).clone();
target.add(oNew);
Полиморфизм позаботится обо всем остальном:)
Второй вариант не является реальным «решением», но его можно использовать, если вам нужен только новый экземпляр массива объектов, параметризованных по типу. Стирание типа происходит только для параметризованных типов, но не для базовых массивов (массивы reified в JVM). Так что, если у нас есть свобода изменять сигнатуру метода и нормально работать с массивами, будет работать следующее:
public <D extends BaseClass> boolean doIt(D[] target) {
try {
D newD = (D) (target.getClass().getComponentType().getConstructor(int.class).newInstance(8));
target[0] = newD;
// The following is optional, if we want to work with Collections internally
List<D> l = new ArrayList<D>(Arrays.asList(target));
l.add(newD);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
Примечание: токены супертипа не будут работать для этой проблемы, если мы не сможем ввести новые параметры. Пожалуйста, поправьте меня, если я ошибаюсь.