2016-11-25 47 views
0

我的目标是实现一个接受类实例的操作,但前提是具体传递类继承自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; 

有人可以解释一下吗?问题是如果我可以编写上面的代码,以便我不会发出警告(并且代码有效)?

+1

你有没有试过Class?扩展集合>'?请注意,进一步向下传递'ArrayList',其中'Class'是预期的。 –

回答

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将接受类从集合继承。

+0

很酷。这是解决方案。 (但我承认:为什么编译器现在快乐的简短解释会对我有所帮助。) –

0

由于在运行时没有可用的通用类型信息,所以类作为通用的“类型令牌”(即在运行时指示特定类型的某种方式)是一个根本不好的选择。

这是更好地利用两种:

  • 的类的实例(相应类型的如列表为空) - 虽然这仅仅是满足类型安全的编译器,不提供任何运行时类型信息。
  • 实际的“类型令牌”类,如GSON's TypeTokenGuice's TypeLiteral

    请注意,这两个类的Javadoc始于:

    表示泛型类型T的Java还没有提供一种方式来表示泛型类型,所以这个类呢。 ...

    一个GSON类型的令牌,是通过TypeToken一个匿名子类创建:

    TypeToken<ArrayList<String>> typeToken = new TypeToken<ArrayList<String>>() {}; 
    

    子类的行为烘烤泛型类型信息到typeToken例如,通过typeToken.getClass().getGenericSuperclass()

    请注意,您不能一般这样做 - 您必须创建具有实际类的子类作为通用参数,而不是类型变量。

相关问题