为了账号安全,请及时绑定邮箱和手机立即绑定

如何确定泛型类型的类?

如何确定泛型类型的类?

红糖糍粑 2019-07-17 16:25:41
如何确定泛型类型的类?我正在创建一个泛型类,在其中一个方法中,我需要知道当前使用的泛型类型的类。原因是我调用的方法之一期望这是一个参数。例子:public class MyGenericClass<T> {   public void doSomething() {     // Snip...     // Call to a 3rd party lib     T bean = (T)someObject.create(T.class);     // Snip...   }}显然,上面的示例不起作用,并导致以下错误:类型参数T的非法类文字。我的问题是:有人知道一个很好的替代方案或解决办法吗?
查看完整描述

3 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

同样的问题:一般信息在运行时被删除,无法恢复。解决方法是在静态方法的参数中传递类T:

public class MyGenericClass<T> {

    private final Class<T> clazz;

    public static <U> MyGenericClass<U> createMyGeneric(Class<U> clazz) {
        return new MyGenericClass<U>(clazz);
    }

    protected MyGenericClass(Class<T> clazz) {
        this.clazz = clazz;
    }

    public void doSomething() {
        T instance = clazz.newInstance();
    }}

很丑,但很管用。


查看完整回答
反对 回复 2019-07-17
?
富国沪深

TA贡献1790条经验 获得超9个赞

我刚刚提到了这个解决方案:


import java.lang.reflect.ParameterizedType;


public abstract class A<B> {

    public Class<B> g() throws Exception {

        ParameterizedType superclass =

            (ParameterizedType) getClass().getGenericSuperclass();


        return (Class<B>) superclass.getActualTypeArguments()[0];

    }

}

如果A由子类提供具体类型:


new A<String>() {}.g() // this will work


class B extends A<String> {}

new B().g() // this will work


class C<T> extends A<T> {}

new C<String>().g() // this will NOT work


查看完整回答
反对 回复 2019-07-17
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

不幸的是,Christoph的解决方案只在非常有限的情况下起作用。[编辑:正如下面的评论,我不再记得我对这句话的推理,这很可能是错误的:“注意,这只会在抽象类中起作用,首先。”下一个困难是g()的直接子类工作。A..不过,我们可以解决这个问题:

private Class<?> extractClassFromType(Type t) throws ClassCastException {
    if (t instanceof Class<?>) {
        return (Class<?>)t;
    }
    return (Class<?>)((ParameterizedType)t).getRawType();}public Class<B> g() throws ClassCastException {
    Class<?> superClass = getClass(); // initial value
    Type superType;
    do {
        superType = superClass.getGenericSuperclass();
        superClass = extractClassFromType(superType);
    } while (! (superClass.equals(A.class)));

    Type actualArg = ((ParameterizedType)superType).getActualTypeArguments()[0];
    return (Class<B>)extractClassFromType(actualArg);}

这将在许多实际情况下起作用,但并非总是如此。考虑:

public class Foo<U,T extends Collection<?>> extends A<T> {}(new Foo<String,List<Object>>() {}).g();

这将抛出一个ClassCastException,因为此处的类型参数不是Class或者是ParameterizedType一点也不,这是TypeVariable T..所以现在你会被困在想找出哪种类型T应该是用来代表兔子洞的,以此类推。

我认为唯一合理的、一般的答案是类似于Nicolas最初的答案-一般来说,如果您的类需要实例化编译时未知的其他类的对象,那么类的用户需要显式地将该类文字(或者可能是一个工厂)传递给您的类,而不仅仅是依赖泛型。


查看完整回答
反对 回复 2019-07-17
  • 3 回答
  • 0 关注
  • 981 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信