获得List <t> </t>的类

时间:2014-05-07 19:30:35

标签: java eclipse maven generics collections

请考虑以下3个Java类:

超级课程:

public abstract class Column<T>
{

    private final Class<T> type;
    private final String name;


    public Column(Class<T> type, String name)
    {
        this.type = type;
        this.name = name;
    }

    public Class<T> getType()
    {
        return type;
    }

    // ...

}

工作子类:

public class FloatColumn extends Column<Float>
{   

    public FloatColumn(String name)
    {
        super(Float.class, name);
    }

    // ...

}

有问题的子类:

public class ListColumn<L extends List<T>, T> extends Column<L>
{   

    public ListColumn(String name)
    {
        super((Class<L>) List.class, name);
    }

    // ...

}

有问题的子类(ListColumn)在Eclipse中编译得很好,Java编译器合规性设置为1.6。但是,当通过Maven编译时(使用JDK编译器,源和目标设置为1.6),Inconvertible types构造函数中super()调用时出现ListColumn错误。

编辑:Eclipse会警告此行(Type safety: Unchecked cast from Class<List> to Class<L>)。

我知道Eclipse不使用JDL编译器,显然它使用的编译器不如JDK编译器严格。

但是,我的问题是如何使这个代码在1.6 JDK编译器上运行。

换句话说,如何使用符合预期Class<L>类型的参数调用超级构造函数,其中L仅限于extends List<T>

最好我只想在ListColumn构造函数中进行更改,而不是在Column类中进行更改。

2 个答案:

答案 0 :(得分:2)

它可能对你有帮助。

super((Class<L>)(Class<?>)List.class, name);

注意:它显示警告,但您可以使用@SuppressWarnings("unchecked")

来禁止它

有关详细信息,请查看Class object of generic class (java)

答案 1 :(得分:0)

假设我按如下方式实例化你的类:

ListColumn<ArrayList<String>, String> listColumn = new ListColumn<ArrayList<String>, String>("column");

现在,您的代码会尝试将List.class投射到Class<ArrayList>,但事实并非如此。

如果您希望允许客户端使用Column泛型类型的子类型,则可以在T类中使用协方差。例如,将Column构造函数更改为:

public Column(Class<? extends T> type, String name)

允许您在ListColumn中调用super而不进行任何演员,因为现在允许List的任何子类型,但是以类型安全方式。

至于欺骗编译器接受任何类型的泛型仅仅警告,你可以使用最脏的“双重投射”技巧,简单地消除泛型,因此编译器将不再能够赶上你的代码:

List<Integer> l = new ArrayList<Integer>();
List<String> s = (List<String>) (List) l;

但这真的是你想要的吗?