Java泛型类型参数

时间:2012-04-13 22:28:15

标签: java generics

我有一个以List<?>为参数的方法。

public static String method(List<?> arg){
     // Do something based on type of the list
}

//I call the method as below
List<ClassA> listA = new ArrayList<ClassA>();
List<ClassB> listB = new ArrayList<ClassB>();
method(listA);
method(listB);

method中,我如何知道argList ClassA还是List ClassB

3 个答案:

答案 0 :(得分:17)

从技术上讲,您 CAN 使用instanceof检查某个对象是否属于某种类型。

然而......那是 一个好主意。

您声明方法的方式,它可以接受任何类型的List,因此它不一定是A或B.

很难说出你想要做什么,但你可能应该让你的方法通用。

你可以这样做:

public static <T> String method(List<T> arg) {
    // We now know that the type of the list is T, which is
    // determined based on the type of list passed to this
    // method.  This would demonstrate the point better if
    // the return type was T, but I'm leaving the return type
    // as String, because that's what your code returns.
}

以下是一个更好的例子

如果你想创建一个返回列表第一个元素的泛型方法,你可以这样做:

public static <T> T firstElement(List<T> theList) {
    if (theList == null) {
        return null;
    }
    T objectOfTypeT = theList.get(0);
    return objectOfTypeT;
}

请注意,返回类型现为T

因为我们使这个方法通用,所以它可以返回List中使用的相同类型。

您通常会返回theList.get(0),但我添加了一行,以使通用的目的更加明显。

语法说明:

  • <T>表示此方法采用一个名为T的类型参数。

  • 紧随其后的T是返回类型(就像你通常会返回String,Integer等...)。

  • List参数中的T是编译器如何知道T到底是什么。

这允许编译器说:“这个方法需要T类型的东西哦看看......列表也是T类型。如果有人将字符串列表传递给这个方法,那么T必须是如果有人将整数列表传递给此方法,则T必须是整数。

相比之下,您的方法可以返回一个字符串,并且不知道列表中使用了什么类型。


也...

如果A和B都扩展了同一个类,名为TheParentClass,你可以像这样声明你的方法:

public static String method(List<? extends TheParentClass> arg)

这样,您就可以了解更多关于参数的可能类型(并且可以从编译时类型检查中受益)。

答案 1 :(得分:4)

来自名为Romain的用户的回答“如果您使用&lt;?&gt;,则表示您不会在任何地方使用参数化类型。要么转到特定类型(在您的情况下,它)似乎是List&lt; String&gt;)或非常通用的List&lt; Object&gt;“

另外,我相信如果你使用问号,编译器将不会捕获类型不匹配,直到运行时(已实现;有效Java的第119页),绕过擦除,并有效地消除了使用泛型类型带来的好处???

回答提问者的问题:如果你使用List&lt;对象&gt;然后尝试将它转换为A或B,可能使用instanceOf,这可能是一种告诉它是什么的方法。我敢打赌,有一种更好的方法可以做到这一点。

答案 2 :(得分:1)

根据您的示例,无法知道List的泛型类型参数是什么。它们在实例级别被删除。