2013-03-13 3 views
2
public abstract class BaseDaoImpl<E extends AbstractEntity> implements BaseDao<E> { 

    ..... 

    public BaseDaoImpl() throws DataAccessException { 
     logger = LoggerFactory.getLogger(E); <<-- error here. 
    } 

В приведенном выше коде я получаю сообщение об ошибке в вызове getLogger(E).Как преобразовать общий параметр в класс

E не может быть решена с переменной

Это имеет смысл, но getLogger(E.class) (или его варианты) не работает.

Я не хочу, чтобы пройти буквальный класс в конструкторе, так что решение, как изменение заголовка конструктора для:
public BaseDaoImpl(Class<E> clazz) ... это не вариант.

Как получить тип класса от E?

Обратите внимание, что ответы на вопросы: How to get class of generic type when there is no parameter of it?
не помогите.

+1

Вы не можете, из-за типа стирание. – SLaks

+0

Java-дженерики не совпадают с шаблонами C++. В Java-генераторах тип стирается во время компиляции. Google «стирание стирания java» для деталей. Это кажется плохим решением, но на самом деле это отличное решение; поскольку он полностью обратно совместим со старой java. – DwB

+0

Возможный дубликат [Получить общий тип класса во время выполнения] (http: // stackoverflow.com/questions/3403909/get-generic-type-of-class-at-runtime) –

ответ

4

Без изменения конструктора вы не можете узнать ничего о E во время выполнения, что вы еще не знали статически. Это потому, что в Java просто нет никакого эффекта времени выполнения общего параметра - компилятор буквально стирает все ссылки на E в генерируемый им код. Поэтому, если вам нужен код, который может определить, с каким классом создается его тип параметра, вам нужно добавить какой-то аргумент (например, объект Class). Вокруг этого нет.

0

Поскольку дженерики реализованы на языке Java с использованием стирания типа, вы не можете делать ничего, что требовало бы информации о времени выполнения. См. this page для получения дополнительной информации.

-1

Уже было answered.

В принципе, вы не можете, если не используете отражение.

Я бы не рекомендовал использовать отражение, но если вы хотите, вы должны быть в состоянии использовать:

GenericClass.class.getTypeParameters() 
+0

Это не совсем правильно. Например, если у меня есть 'class Foo extends BaseDaoImpl ', то вы все равно не сможете его получить. – newacct

+0

Он должен работать, если у вас есть 'class Foo extends BaseFoo 'хотя. Если вы пытаетесь получить класс E, очевидно, что у вас будут проблемы, так как E не является классом! – CorayThan

+0

Получение «Тип» - это не то же самое, что получить «Класс» – jpaugh

2

Это возможно отражение как отметил @CorayThan. Простой способ сделать это состоит из сигнатуры метода

interface BaseDao<E> 
    E find(long id); 

class FooDao implements BaseDao<Foo> 
    Foo find(long id) 

Так типа Е можно найти через

this.getClass().getDeclaredMethod("find", long.class).getReturnType(); 

Однако это является очень хороший вариант, чтобы пройти в более Class конструктор. Поскольку конструктор не предназначен для вызова пользовательскими кодами, многословие здесь не является проблемой.

abstract class BaseDaoImpl<E> 

    BaseDaoImpl(Class<E> clazz) 

class FooDao extends BaseBaoImpl<Foo> 

    FooDao() 
     super(Foo.class); 

// usages: 

BaseDao<Foo> fooDao = new FooDao(); // clean & simple API 
+0

«Возможно» «Не в общем». Что делать, если у вас вместо этого есть класс FooDao реализует BaseDao '? – newacct

Смежные вопросы