我正在研究现有代码。在一个类中,我具有以下方法,具有以下语法:
public Response getData(Request serviceRequest, Class<? extends APIResponse> expectedResponseClass)
{
}
我的问题是,我无法理解此方法的第二个参数。
有人可以告诉我,第二个参数是什么,我们应该如何理解?
谢谢!
修改为证明我们也可以将子类作为参数传递给期望超类的方法
超类.java
public class Superclass {}
一个.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");
}
}
最佳答案
如果方法的参数类型为Class<APIResponse>
,则将指示类型参数为Class
的APIResponse
对象,而不是其任何子类。 Class
对象的type参数是它表示的类。换句话说,唯一有效的参数将是APIResponse
类对象(或null
)。
相反,Class<? extends APIResponse>
表示类型参数为Class
或其任何子类的APIResponse
对象。这意味着,如果您有APIResponse
的子类(我将其称为MyAPIResponse
),则可以将其类对象传递给此方法。该对象的类型为Class<MyAPIResponse>
,适合Class<? extends APIResponse>
内部。
您可能想知道为什么会这样。为什么不能将Class<MyAPIResponse>
对象放入Class<APIResponse>
变量中?答案是因为它会破坏Java的类型安全性。这不是立即显而易见的,并且我无法用Class
来解释它(该类没有任何类型的方法,具体取决于其类型参数),所以我将举一个使用不同泛型的示例类别:ArrayList
。这里YourAPIResponse
是APIResponse
的另一个子类。
ArrayList<APIResponse> list = new ArrayList<MyAPIResponse>();
list.add(new YourAPIResponse());
如果
ArrayList<MyAPIReponse>
对象可以放入ArrayList<APIResponse>
变量中,则可以编译该代码-但结果是将YourAPIResponse
对象插入List<MyAPIResponse>
中,从而破坏了Java的类型安全性。这就是为什么您不能这样做。显然,这限制了纯泛型的功能。为了解决这个问题,发明了通配符泛型。因此,您可以执行以下操作:
ArrayList<? extends APIResponse> list = new ArrayList<MyAPIResponse>();
但是,如果您要从上方添加第二行,它将无法编译,因为编译器无法验证参数的运行时类型是否适合
ArrayList
的type参数。因此,类型安全性得以保留。