Отражение Java на неизвестном родовом - PullRequest
1 голос
/ 20 февраля 2011

Я играю в учебных целях с Javas Generics и пытаюсь использовать Reflection на них.В тот же момент, когда я понял половину, я сталкиваюсь с проблемами, которые я не видел, как решить.У меня есть простой класс Box:

public class ReflectionBox<E>  {
    protected E e;

    public ReflectionBox(){}
    public ReflectionBox(E element){ this.e = element; }

    public void set(E element){ e = element; }
    public E get(){ return e; }
    //... a few reflection methods...
}

Я расширил этот класс, чтобы попытаться реализовать интерфейс с ним.Этот интерфейс вынуждает меня написать следующее утверждение:

public static final Parcelable.Creator<ParcelableBox<?>> CREATOR = 
        new Parcelable.Creator<ParcelableBox<?>>() {
    @Override
    public ParcelableBox<?> createFromParcel(Parcel source) {
        return new ParcelableBox<Object>(source);
    }
}

Возможно ли получить информацию о классе из ? с помощью Reflection?Я не могу использовать методы из Object, чтобы отразить, какой класс помещен внутрь, ни создать экземпляр new ParcelableBox<?>(? element). Посылка не является тем классом, каким должен быть E, но мой класс находится в этой посылке и должен быть классом?.


РЕДАКТИРОВАТЬ: Привет, спасибо за все ответы: так как многие пользователи не понимают, что я пытаюсь сделать: есть интерфейс Parcelable, который, я думаю, работает какПоток данных, в который можно помещать объекты-члены.Вы используете что-то вроде parcel.writeString(String string) или parcel.writeValue(Object value) для хранения и parcel.readValue в том же направлении, в котором вы положили его внутрь.Для обучения я хочу реализовать это в общем.Так что я хочу иметь возможность хранить в Parcel и читать из него, используя Reflection.потому что CREATOR является статическим, я не могу использовать E.

Ответы [ 3 ]

4 голосов
/ 20 февраля 2011

Нет, это невозможно. Обобщения также называются «стиранием», потому что они удаляются из класса во время компиляции. Обобщение - это функция времени компиляции, которая не существует во время выполнения, поэтому нет способа извлечь эту информацию.

Но есть обходной путь. Создайте специальное поле Class<?> type; и укажите тип, который хотите получить. Тогда просто восстанови это.

Кстати, у вас уже есть почти это решение. У вас есть поле protected E e;. Таким образом, вы можете использовать e.getClass() для определения типа.

0 голосов
/ 20 февраля 2011

Я попробовал следующий код, чтобы сгенерировать реализацию DAO для кода на основе гибернации, и это помогло, когда вы не передали объект 'T' в конструктор.

public class Dao<T> {    
private Class<T> type;

    public Dao() {
        if (getClass().getGenericSuperclass() instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) getClass()
                    .getGenericSuperclass();
            this.type = (Class<T>) (parameterizedType.getActualTypeArguments()[0]);
        }
    }

    public T findByPrimaryKey(Serializable key) {
        return (T) sessionFactory.getCurrentSession().get(type, key);
    }
}

Из вашего примера и описания не понятно, что нужно; это поможет мне ответить лучше, если пример понятен.

0 голосов
/ 20 февраля 2011

Поскольку вы знаете, что тип E будет Parcel для экземпляра CREATOR, вы можете просто написать его как:

public static final Parcelable.Creator<ParcelableBox<Parcel>> CREATOR = 
        new Parcelable.Creator<ParcelableBox<Parcel>>() {
    @Override
    public ParcelableBox<Parcel> createFromParcel(Parcel source) {
        return new ParcelableBox<Parcel>(source);
    }
}

Так что никакого отражения не потребуется. Хотя это действительно зависит от того, что вы пытаетесь сделать. Я не смог понять это полностью из небольшого примера.

Если вам действительно нужно использовать рефлексию, это будет сложно, потому что общая информация не сохраняется во время выполнения, поэтому вы не можете делать такие вещи, как obj instanceof E. Все, что вы можете сделать, это obj.getClass(), что может быть весьма ограничивающим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...