Здесь есть некоторая путаница.Из-за удаления типа вы не можете получить информацию о типе из параметризованного типа во время выполнения, например:
Class<E> cls = E.getClass(); // Error.
E e = new E(); // Error.
Однако вы можете получить информацию о параметризованном типе во время компиляции из объявления класса, поля и метода с помощью ParameterizedType#getActualTypeArguments()
.
abstract class AbstractExecutor<E> {
public void execute() throws Exception {
List<E> list = new ArrayList<E>();
Class<E> cls = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
E e = cls.getConstructor(String.class).newInstance("Gate");
list.add(e);
System.out.println(format(list));
}
// ...
}
Обновление : относительно того, рекомендуется это или нет, хотя это будет работать, это чувствительно к проблемам времени выполнения всякий раз, когда незначительные изменения в классеобъявление происходит.Вы, как разработчик, должны документировать это правильно.В качестве совершенно другой альтернативы вы можете использовать полиморфизм.
abstract class AbstractExecutor<E> {
public void execute() throws Exception {
List<E> list = new ArrayList<E>();
E e = create("Gate");
list.add(e);
System.out.println(format(list));
}
public abstract E create(String name);
// ...
}
и реализовать UserExecutor
соответственно.
class UserExecutor extends AbstractExecutor<User> {
@Override
public User create(String name) {
return new User(name);
}
// ...
}