我正在处理现有代码。在其中一个类中,我有这个方法,使用下面的语法:
public Response getData(Request serviceRequest, Class<? extends APIResponse> expectedResponseClass)
{
}
我的问题是,我无法理解这种方法的第二个参数。
有人可以告诉我,第二个参数是什么,我们应该如何理解?
谢谢!
修改为证明我们也可以将子类作为参数传递给期望超类的方法
Superclass.java
public class Superclass {}
One.java
public class One extends Superclass{}
Main.java
public class Main {
public static void main(String args[]) {
One one = new One();
Main main = new Main();
main.mainMethod(one);
}
public void mainMethod(Superclass sc) {
System.out.println("Inside the Main Method");
}
}
答案 0 :(得分:6)
Class<? extends APIResponse>
是有界通配符的示例。这意味着它可以是类APIResponse
本身的类,或者它的某个子类。
如果您改为使用Class<APIResponse>
,则只能在APIResponse
类型的类上调用该方法,而不能调用其任何子类型。
请查看Wildcards tutorial了解详情。
答案 1 :(得分:1)
第二个参数是Class
类型的实例,它对应于APIResponse
的子类(或APIResponse
本身)。
请注意,此调用中没有涉及APIResponse
(或子类)的实例,因为您似乎暗示某些注释。
答案 2 :(得分:1)
如果方法的参数类型为Class<APIResponse>
,则表示类型参数为Class
的{{1}}对象 - 不是它的任何子类。 APIResponse
对象的类型参数是它所代表的类。换句话说,唯一有效的参数是Class
类对象(或APIResponse
)。
相比之下,null
表示Class<? extends APIResponse>
对象,其类型参数为Class
或其任何子类。这意味着如果你有一个APIResponse
的子类(我称之为APIResponse
),你可以将它的类对象传递给这个方法。该对象的类型为MyAPIResponse
,适合Class<MyAPIResponse>
。
你可能想知道为什么会这样。为什么不能将Class<? extends APIResponse>
对象放入Class<MyAPIResponse>
变量?答案是因为它会破坏Java的类型安全性。这不是很明显,我无法用Class<APIResponse>
来解释它(该类没有任何带参数的方法,具体取决于它的类型参数),所以我将举例说明不同的通用类:Class
。这里ArrayList
是YourAPIResponse
的另一个子类。
APIResponse
如果ArrayList<APIResponse> list = new ArrayList<MyAPIResponse>();
list.add(new YourAPIResponse());
对象可以放入ArrayList<MyAPIReponse>
变量,则此代码将编译 - 但效果是将ArrayList<APIResponse>
对象插入YourAPIResponse
,从而打破了Java的类型安全性。这就是你不能那样做的原因。
这显然对纯粹的仿制药可以做的事情有很多限制。为了解决这个问题,发明了通配符泛型。所以你可以这样做:
List<MyAPIResponse>
但是如果你要从上面添加第二行,它将无法编译,因为编译器无法验证参数的运行时类型是否适合ArrayList<? extends APIResponse> list = new ArrayList<MyAPIResponse>();
的类型参数。所以类型安全得以保留。
答案 3 :(得分:0)
这是Java Generics参数。这意味着第二个参数应该是Class
,该类扩展了APIResponse
。
答案 4 :(得分:0)
它表示第二个参数可以是APIResponse的任何子类。