我正在研究现有代码。在一个类中,我具有以下方法,具有以下语法:

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>,则将指示类型参数为ClassAPIResponse对象,而不是其任何子类。 Class对象的type参数是它表示的类。换句话说,唯一有效的参数将是APIResponse类对象(或null)。

相反,Class<? extends APIResponse>表示类型参数为Class或其任何子类的APIResponse对象。这意味着,如果您有APIResponse的子类(我将其称为MyAPIResponse),则可以将其类对象传递给此方法。该对象的类型为Class<MyAPIResponse>,适合Class<? extends APIResponse>内部。

您可能想知道为什么会这样。为什么不能将Class<MyAPIResponse>对象放入Class<APIResponse>变量中?答案是因为它会破坏Java的类型安全性。这不是立即显而易见的,并且我无法用Class来解释它(该类没有任何类型的方法,具体取决于其类型参数),所以我将举一个使用不同泛型的示例类别:ArrayList。这里YourAPIResponseAPIResponse的另一个子类。

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参数。因此,类型安全性得以保留。

07-24 15:04