【问题标题】:Generics: Creating parameterized class argument泛型:创建参数化类参数
【发布时间】:2011-11-25 11:59:42
【问题描述】:

如何将参数化的 Class 对象用作方法参数?

class A<T>
{
    public A(Class<T> c)
    {
    }

    void main()
    {
        A<String> a1 = new A<String>(String.class);     // OK
        A<List<String>> a2 = new A<List<String>>(List<String>.class);  // error
        A<List<String>> a3 = new A<List<String>>(Class<List<String>>);  // error
    }
}

您可能会问,我为什么要这样做?我有一个参数化类,其类型是另一个参数化类,并且其构造函数需要其他类类型作为参数。我知道运行时类没有关于它们的类型参数的信息,但这不应该阻止我在编译时这样做。看来我应该能够指定诸如List&lt;String&gt;.class 之类的类型。是否有其他语法可以做到这一点?

这是我的真实用例:

public class Bunch<B>
{
    Class<B> type;

    public Bunch(Class<B> type)
    {
        this.type = type;
    }

    public static class MyBunch<M> extends Bunch<List<M>>
    {
        Class<M> individualType;

        // This constructor has redundant information.
        public MyBunch(Class<M> individualType, Class<List<M>> listType)
        {
            super(listType);
            this.individualType = individualType;
        }

        // I would prefer this constructor.
        public MyBunch(Class<M> individualType)
        {
            super( /* What do I put here? */ );
            this.individualType = individualType;
        }
    }
}

这可能吗?

【问题讨论】:

标签: java generics arguments


【解决方案1】:

直接投射怎么样?

super((Class<List<M>>)List.class);

类文字不会有你想要的类型参数。

【讨论】:

    【解决方案2】:

    请记住,您不会在运行时将 List 作为类获取,正确的方法可能是按照 BalusC 告诉您的那样使用 TypeToken。没有 TypeToken,你不能强制转换为 List,但你可以创建这样的东西:

    public static class MyBunch2<List_M extends List<M>, M> extends Bunch<List_M>
    {
        Class<M> individualType;
    
        @SuppressWarnings("unchecked")
            public MyBunch2(Class<M> individualType)
        {
            super((Class<List_M>) List.class);
            this.individualType = individualType;
        }
    }
    

    由于List_M extends List&lt;M&gt; 这并不像您希望的那样类型安全,但也许已经足够好了。创建实例会像写一样难看

    MyBunch2<List<String>, String> a = new MyBunch2<List<String>, String>(String.class);
    

    但您可以使用工厂方法对其进行改进

    public static <M2> MyBunch2<List<M2>, M2> of(Class<M2> individualType){
        return new MyBunch2<List<M2>, M2>(individualType);
    }
    

    然后写

    MyBunch2<List<String>, String> b = MyBunch2.of(String.class);
    

    如果你使用的是eclipse,代码辅助会帮你写出丑陋的类MyBunch2,String>

    当然,在运行时,this.type 将是 java.util.List,而不是 java.util.List 要正确处理,请使用 TypeToken。

    ---继续---

    你甚至可以制作另一个课程

    public static class MyBunch3<M> extends MyBunch2<List<M>, M>
    {
            public MyBunch3(Class<M> individualType) {
                super(individualType);
            }
    }
    

    然后创建实例为

    MyBunch3<String> c = new MyBunch3<String>(String.class);
    

    必须有一种方法可以在一个班级中做到这一点……但我想不通

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多