使用java Generics和反射导致此编译错误的原因是什么?

时间:2013-02-04 04:29:24

标签: java generics reflection

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

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)

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

为什么不编译?

3 个答案:

答案 0 :(得分:4)

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

您已键入方法,以便接受M是A的子类型

现在,您正在使用&#39; objectClass&#39;这是A 的子类型,但不一定是M的子类型。

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

如果你能解释一下你想要做些什么,我可以提供一个解决方案。

答案 1 :(得分: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.
}

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

答案 2 :(得分:1)

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

类告诉编译器对象的类型是A的子类,但是它并没有告诉编译器用于转换的确切类型。

您的问题是您正在尝试用Generic替换Polymorphism。当你正在努力学习时,Generic不是新的现代多态性方法。