3

我有一个通用方法,它应该类似于递归,但为每次调用调用不同的方法实例。

public <M extends A> void doSomething(Class<M> mClass, M mObject)
{
    // ... Do something with mObject.

    A object = getObject();
    Class<? extends A> objectClass = object.getClass();

    doSomething(objectClass, objectClass.cast(object)); // Does not compile.
}

private A getObject() {...}

问题是带有注释的行无法编译,出现以下错误:

MainTest 类型中的方法 doSomething(Class, M) 不适用于参数 (Class, capture#3-of ? extends A)

我不太明白如果编译器可以doSomething用 M = "? extends A" 调用,为什么编译器不编译。

为什么不编译?

4

3 回答 3

4

好的,这是一个粗略的解释

您已经输入了您的方法,以便它接受 M ,它是 A 的子类型

现在您正在使用“objectClass”调用您的方法,它是 A 的子类型,但不一定是 M 的子类型。

因此编译器抱怨......

如果您能解释一下您正在尝试做的更多事情,我可以提供解决方案。

于 2013-02-04T04:42:08.263 回答
2

该语言不跟踪这样的通配符(似乎)。您需要做的是捕获该通配符,这可以通过使用类型推断的方法调用来完成。

public <M extends A> void doSomething(Class<M> mClass, M mObject) {
    // ... Do something with mObject.

    A object = getObject();
    Class<? extends A> objectClass = object.getClass();
    privateSomething(objectClass, object);
}
private <T extends A> void privateSomething(Class<T> objectClass, A object) {
    doSomething(objectClass, objectClass.cast(object)); // Should compile.
}

与往常一样,虽然反射有一些用途,但它通常是混乱的标志。

于 2013-02-04T05:14:19.463 回答
1

当您要求编译器执行强制转换时,必须知道执行强制转换的确切类型。告诉编译器你不知道它是 A 的子类的确切类型摘录是不够的。

Class 告诉编译器对象的类型是 A 的子类,但它不会告诉编译器要用于强制转换的确切类型。

您的问题是您试图用通用替换多态性。当您正在艰难地学习时,Generic 并不是做多态的新的现代方式。

于 2013-02-04T05:00:52.250 回答