【问题标题】:Java Reflection on unknown GenericJava 对未知泛型的反射
【发布时间】:2011-02-20 12:38:49
【问题描述】:

我正在使用 Java 泛型进行学习,并尝试对它们使用反射。 在我认为我理解了一半的同时,我遇到了我没有找到解决方法的问题。 我有一个简单的 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);
    }
}

是否可以使用反射从? 获取类信息?我不能在上面使用Object 的方法来反映放入了哪个类,也不能实例化new ParcelableBox&lt;?&gt;(? element)。包裹不是E 应该是的类,但我的类是 在那个包裹中,应该是? 的类。


编辑: 嗨,感谢所有答案:由于许多用户不明白,我正在尝试做什么: 有一个接口Parcelable,我认为它可以用作数据流,您可以在其中放置对象成员。您使用 parcel.writeString(String string)parcel.writeValue(Object value) 之类的东西来存储,parcel.readValue 与您放入的方向相同。为了学习,我想将其实现为通用的。所以我希望能够存储到包裹,并使用反射从中读取。 因为 CREATOR 是静态的,所以我不能使用 E。

【问题讨论】:

    标签: java android generics reflection


    【解决方案1】:

    不,这是不可能的。泛型也称为“擦除”,因为它们在编译期间从类中删除。泛型是运行时不存在的编译时特性,因此无法检索此信息。

    但是有一个解决方法。创建特殊字段Class&lt;?&gt; type; 并将您希望检索的类型放在那里。然后只需检索它。

    顺便说一句,您几乎已经有了这个解决方案。您有一个字段protected E e;。因此,您可以使用e.getClass() 来确定类型。

    【讨论】:

    • @AlexR 你能更具体地说明“解决方法”吗?我不能让它工作,因为我和拉斐尔犯了同样的错误
    【解决方案2】:

    既然您知道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(),这可能是非常有限的。

    【讨论】:

    • 不,Parcelable.Creator&lt;ParcelableBox&lt;Parcel&gt;&gt;() 正是我想要避免的,因为 Parcel 存储了一个 E 的对象,我在 E 的实例上使用反射。
    【解决方案3】:

    我尝试使用以下代码为基于休眠的代码生成 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);
        }
    }
    

    从您的示例和描述中,不清楚需要什么;如果示例清楚,将有助于我更好地回复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 1970-01-01
      • 2012-06-25
      相关资源
      最近更新 更多