如何使用泛型正确指定Class <! - ? - >参数

时间:2016-11-25 14:52:00

标签: java generics

我的目标是实现一个接受类实例的操作,但前提是具体传递的类继承自Collection。

我的代码上出现了无法解决的编译器警告。

package com.fun.with.generics;

import java.util.ArrayList;
import java.util.Collection;

public class AcceptTypedClass
{
    // Warning here on 'Collection': ... raw type, references should be parameterized.
    private static void printCollectionClass( Class<? extends Collection> c )
    {
        System.out.println( c.getName() );
    }

    public static void main( String[] args )
    {
        // Warning here on ArrayList: ... raw type, references should be parameterized.
        Class<ArrayList> arrayList = ArrayList.class;
        printCollectionClass( arrayList );
    }
}

我确实理解了警告消息,但如果我通过添加如下所示的缺失类型参数来修复警告,则会出现错误。

Class<ArrayList<?>> arrayList = ArrayList.class;

有人可以解释一下吗?问题是我是否可以编写上面的代码,以便我没有得到警告(并且代码有效)?

2 个答案:

答案 0 :(得分:0)

Class作为泛型&#34;类型令牌&#34;是一个根本不好的选择,即在运行时指示特定类型的一些方法,因为在运行时没有可用的泛型类型信息。

使用它们会更好:

  • 类的实例(例如,适当类型的空列表) - 虽然这只是满足类型安全的编译器,但不提供任何运行时类型信息。
  • 一个实际的&#34;类型令牌&#34;类,如GSON's TypeTokenGuice's TypeLiteral

    请注意,这两个类的Javadoc以:

    开头
      

    表示泛型类型T. Java还没有提供表示泛型类型的方法,所以这个类就是这样。 ...

    通过创建TypeToken的匿名子类:

    来创建GSON类型令牌
    TypeToken<ArrayList<String>> typeToken = new TypeToken<ArrayList<String>>() {};
    

    子类化行为通过typeToken将泛型类型信息烘焙到typeToken.getClass().getGenericSuperclass()实例中。

    请注意,您不能一般地执行此操作 - 您必须创建子类,将实际类作为通用参数,而不是类型变量。

答案 1 :(得分:0)

您可以将printCollectionClass方法更改为

private static <T extends Collection<?>> void printCollectionClass(Class<T> c) {
        System.out.println(c.getName());
    }
public static void main(String[] args) {
        printCollectionClass(ArrayList.class);
    }

此处printCollectionClass将接受从集合继承的类。