Java对未知泛型的反射

发布于 2024-10-18 09:39:08 字数 1320 浏览 1 评论 0原文

我正在玩 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);
    }
}

Is it possible to get Class informations from ? using Reflection?我无法在其上使用 Object 中的方法来反映放入其中的类,也无法实例化 new ParcelableBox(? element)。Parcel 不是E 应该是班级,但我的班级是 在该 Parcel 中,并且应该是 ? 的类。


编辑: 您好,感谢您的所有回答:由于许多用户不明白,我想要做什么: 有一个接口Parcelable,我认为它作为数据流工作,您可以在其中放置对象成员。您使用类似 parcel.writeString(String string)parcel.writeValue(Object value) 的内容来存储和 parcel.readValue 在同一方向当你把它放进去时。为了学习,我想将其实现为通用的。所以我希望能够存储到 Parcel,并使用 Reflection 读取它。 因为 CREATOR 是静态的,所以我不能使用 E。

I'm playing for learning purposes with Javas Generics and try to use Reflection on them.
In the same moment I thoght I understand the half of it, I'm running into problems I didn't see a way to solve.
I have a simple Box class:

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...
}

I extended this Class to try to implement an Interface with it. This Interface forces me to write an statement like this:

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

Is it Possible to get Class informations from ? using Reflection? I cannot use methods from Object on it to reflect which Class is put inside, neither instanciate a new ParcelableBox<?>(? element).The Parcel isn't the Class which E should be, but my Class is
IN that Parcel and should be the Class of ?.


EDIT:
Hi, thanks for all the answers: As many User don't understand, what I'm trying to do:
There is an Interface Parcelable,which I think it works as a Data Stream, in which You can put Object members. You Use something like parcel.writeString(String string) or parcel.writeValue(Object value) to store and parcel.readValue in the same direction as you put it inside. For learning I wanna implement this into a generic. So I wanna be able to store to Parcel, and read from it using Reflection.
because CREATOR is static I cannot use E.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情徒 2024-10-25 09:39:08

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

但有一个解决方法。创建特殊字段 Class; type; 并将您想要检索的类型放在那里。然后就可以取回它了。

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

No, it is impossible. Generics are also called "erasures" because they are removed from the class during compilation. Generics are compile time feature that does not exist at runtime, so there is not way to retrieve this information.

But there is a workaroud. Create special field Class<?> type; and put there the type yo wish to retrieve. Then just retrieve it.

BTW you already have almost this solution. You have a field protected E e;. So, you can use e.getClass() to determine the type.

放血 2024-10-25 09:39:08

由于您知道 CREATOR 实例的 E 类型将是 Parcel,因此您可以将其写为:

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() ,这可能非常有限。

Since you know the type of E is going to be Parcel for the CREATOR instance you can just write it as:

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);
    }
}

So no reflection would be necessary. Although it really depends on what you are trying to do. I wasn't able to figure it out completely from you small example.

If you really need to use reflection then it will be difficult, because generic information is not stored at runtime, so you cannot do things like obj instanceof E. All you can do is obj.getClass() which might be quite limiting.

尐籹人 2024-10-25 09:39:08

我尝试了以下代码来为基于 hibernate 的代码生成 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);
    }
}

从你的例子和描述来看,并不清楚需要什么;如果例子清楚的话,这将有助于我更好地回答。

I tried the following code to generify DAO implementation for hibernate based code and it helped when you don't pass the 'T' object to constructor.

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);
    }
}

From your example and description, it is not clear what is needed; it will help me to reply better if the example is clear.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文