Java:无法理解方法语法

时间:2012-01-09 08:43:34

标签: java

我正在处理现有代码。在其中一个类中,我有这个方法,使用下面的语法:

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");
    }

}

5 个答案:

答案 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。这里ArrayListYourAPIResponse的另一个子类。

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的任何子类。