Получить универсальный тип расширяющегося универсального класса в конструкторе суперкласса в Java? - PullRequest
0 голосов
/ 10 января 2012

У меня есть abstract class Abstr<T> и расширение class Ext<T>.Мне нужно Abstr, чтобы узнать, с каким T его расширение было инициализировано, чтобы он мог вернуть этот тип.До сих пор я делал это, передавая тип конструктору, а затем вызывая суперконструктор для его сохранения.Но я думаю, это должно работать и с отражениями.Как я уже говорил:

public abstract class Abstr<T> {

    private Class<T> type;

    public Abstr(Class<T> _class) {
        this.type = _class;
    }

}

public class Ext<T> extends Abstr<T> {

    public Ext(Class<T> _class) {
        super(_class);
    }

}

public void someMethod() {
    Ext<String> ext = new Ext<String>(String.class);
}

Использование отражений должно избавить меня от вызова любого конструктора, так как расширяющийся конструктор по умолчанию вызовет конструктор по умолчанию абстрактных классов, который затем должен сохранить тип вызывающего конструктора:

public Abstr() {    
    this.type = (Class<D>) this.getClass().getTheTypeParameter(); // something along these lines
}

Спасибо!

Ответы [ 4 ]

3 голосов
/ 10 января 2012

Единственный случай, когда он работает, это когда у вас есть неуниверсальный класс с родителем-родителем.Примером может быть:

class Trick<T> {
    T t;
}

public class GenericTest {
    public static void main(String[] args) {
        Trick<Set<String>> trick = new Trick<Set<String>>() {
        };

        // Prints "class org.acm.afilippov.GenericTest$1"
        System.out.println(trick.getClass());
        // Prints "org.acm.afilippov.Trick<java.util.Set<java.lang.String>>"
        System.out.println(trick.getClass().getGenericSuperclass());
    }
}

Для дальнейшего чтения обратитесь к учебнику Reflecting generics - ответ есть, но слишком долго его цитировать и не чувствовать, как будтоукрасть код.Поэтому, пожалуйста, прочитайте:)

1 голос
/ 10 января 2012

Общий тип Abstr: T Это все, что вы можете получить с помощью отражения.

Если вы хотите упростить свой код, вы можете написать.

public class Ext<T> extends Abstr<T> {
    protected Ext(Class<T> _class) {
        super(_class);
    }

    public static <T> Ext<T> of(Class<T> _class) { return new Exit<T>(_class); }
}

Ext<String> ext = Ext.of(String.class);
1 голос
/ 10 января 2012

Если вам действительно нужен метод в Abstr, подобный

public Class<T> getType()

, у вас нет другого выбора, кроме как передать значение Class в конструкторе (или в любом другом методе).Вы не можете получить Class из T из-за стирания типа , что в основном сводится к тому, что T недоступен во время выполнения, только во время компиляции.

1 голос
/ 10 января 2012

Это может не всегда работать, так как, если у вас просто есть new Ext<String>() в каком-либо методе, для этого типа нет данных об отражении.

Таким образом, Ext<String> ext = new Ext<String>(String.class); потеряет информацию о типе во время выполнения (стирание типа), что приведет к Ext ext = new Ext(String.class);.

Если у вас есть такие поля, как private Ext<String> stringExt или конкретные подклассы, такие как StringExt extends Ext<String>, у вас есть данные отражения, которые вы можете получить.

Вот небольшая статья с некоторым источником, который можно использовать для получения данных об отражении для конкретных подклассов (и, возможно, для полей, но я этого не проверял): http://www.artima.com/weblogs/viewpost.jsp?thread=208860

Как я уже сказал, мы используем скорректированную версию этого кода для получения параметров типа для конкретных подклассов.

Итак, у нас есть что-то вроде этого:

class AbstractDAO<T entityType> {
  protected Class<?> entityClass;

  protected AbstractDAO() {
    //ReflectionUtil is our adjusted version of code in the link above
    entityClass = ReflectionUtil.getTypeArguments(AbstractDAO.class, getClass() ).get(0);
  }
}

//Here entityClass is User.class
class UserDAO extends AbstractDAO<User> { ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...