I am working on an existing code. In one of the classes I have this method, with the folowing syntax:
public Response getData(Request serviceRequest, Class<? extends APIResponse> expectedResponseClass)
{
}
My question is, I couldn’t understand the second parameter of this method.
Could anybody please tell me, what is that second parameter, and how should we must understand that?
Thank you!
Modified as to prove that we can pass the subclass also as a parameter to a method which expects superclass
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");
}
}
If the method’s parameter type were
Class<APIResponse>, that would indicate aClassobject whose type parameter wasAPIResponse—not any subclass of it. AClassobject’s type parameter is the class that it represents. In other words, the only valid parameter would be theAPIResponseclass object (ornull).By contrast,
Class<? extends APIResponse>indicates aClassobject whose type parameter isAPIResponseor any subclass of it. That means that if you have a subclass ofAPIResponse(I’ll call itMyAPIResponse), you can pass its class object to this method. That object’s type isClass<MyAPIResponse>, which fits insideClass<? extends APIResponse>.You may be wondering why this is so. Why can’t you put a
Class<MyAPIResponse>object into aClass<APIResponse>variable? The answer is because it would break Java’s type safety. This isn’t immediately obvious, and I can’t explain it in terms ofClass(that class doesn’t have any methods with parameters depending on its type parameter), so instead I’ll give an example using a different generic class:ArrayList. HereYourAPIResponseis another subclass ofAPIResponse.If an
ArrayList<MyAPIReponse>object could fit into anArrayList<APIResponse>variable, then this code would compile—but the effect would be to insert aYourAPIResponseobject into aList<MyAPIResponse>, thereby breaking Java’s type safety. And that’s why you can’t do that.This obviously puts a lot of limits on what you can do with pure generics. To get around this, wildcard generics were invented. So you can do this:
But if you were to then add the second line from above, it wouldn’t compile, because the compiler can’t verify that the runtime type of the argument fits inside the type parameter of the
ArrayList. And so type safety is preserved.