我有一个方法,它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);
Run Code Online (Sandbox Code Playgroud)
在method
,我怎么知道,如果arg
是List
的ClassA
还是List
的ClassB
?
jah*_*roy 18
从技术上讲,你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.
}
Run Code Online (Sandbox Code Playgroud)
这是一个更好的例子:
如果要创建一个返回列表第一个元素的泛型方法,可以这样做:
public static <T> T firstElement(List<T> theList) {
if (theList == null) {
return null;
}
T objectOfTypeT = theList.get(0);
return objectOfTypeT;
}
Run Code Online (Sandbox Code Playgroud)
请注意,现在返回类型T
.
因为我们使这个方法通用,它可以返回List中使用的相同类型.
你通常只会返回theList.get(0)
,但我添加了一行来使泛型的目的更加明显.
语法说明:
的<T>
指示,该方法需要一个名为T一种类型的参数
在T
紧随的返回类型(就像你通常会返回字符串,整数,等...).
将T
在列表参数是编译器如何知道到底是什么一个T
是.
这允许编译器说:" 这个方法需要T类型的东西.看看......列表也是T类型.如果有人将一个字符串列表传递给这个方法,那么T必须是一个字符串.如果有人通过这个方法的整数列表,T必须是一个整数. "
相反,您的方法只能返回一个String,并且不知道List中使用了什么类型.
也...
如果A和B都扩展了同一个类,名为TheParentClass,你可以像这样声明你的方法:
public static String method(List<? extends TheParentClass> arg)
Run Code Online (Sandbox Code Playgroud)
这样,您就可以了解更多关于参数的可能类型(并且可以从编译时类型检查中受益).
来自名为Romain的用户的回答 “如果您使用 <?>,则意味着您不会在任何地方使用参数化类型。要么转到特定类型(在您的情况下似乎是 List<String>),要么转到非常通用的 List<Object> "
另外,我相信,如果您使用问号,编译器将不会捕获类型不匹配,直到运行时(具体化;有效Java的第119页),绕过擦除,并有效地消除您从使用泛型类型中获得的好处???
回答发问者的问题:如果您使用 List< Object> 然后尝试将其转换为 A 或 B ,可能使用 instanceOf ,这可能是一种告诉它是什么的方法。我敢打赌有比这更好的方法。