5
interface A {
    String n();
}
class B implements A {
    @Override
    public String n() { return "asdf"; }
}
interface C<T extends A> {
    T m(T t);
}
class D implements C<B> {
    @Override
    public B m(B b) {
        return b;
    }
}

Class<C<? extends A>> x = D.class;

最后一行有错误

Type mismatch: cannot convert from Class<D> to Class<C<? extends A>>

这对我来说看起来非常好,但也许我错过了类型通配符如何工作的一些微妙之处。有没有办法可以更改最后一行的类型?我需要这个参考,因为我打算稍后再做:

B b = new B();
A y = x.newInstance().m(b);

这也有错误

The method m(capture#1-of ? extends A) in the type C<capture#1-of ? extends A> is not applicable for the arguments (B)

但是,如果我在没有通配符和捕获的情况下使用它,它可以正常工作:

A z = D.class.newInstance().m(b);

不幸的是,我现在有点坚持这一点,任何帮助将不胜感激。

编辑:删除this.参考

编辑:将 x 更改为

Class<? extends C<? extends A>> x = D.class;

它有效。但是仍然出现错误x.newInstance().m(b)

The method m(capture#2-of ? extends A) in the type Test.C<capture#2-of ? extends A> is not applicable for the arguments (B)
4

2 回答 2

6

对,只关注最后一部分:

但是在 x.newInstance().m(b) 上仍然出现错误

The method m(capture#2-of ? extends A) in the type
Test.C<capture#2-of ? extends A is not applicable for the arguments (B)

确实——这是完全有道理的。因为您的代码中没有任何内容表明您实际上有一个C<B>. 编译器所知道的是,newInstance它返回了某种类型的实例,该实例为某种类型的实现。它怎么会知道那是?C<X>XAB

如果你想打电话m(b),你需要一个C<B>,这意味着你的声明需要是

Class<? extends C<B>> x = D.class;

此时,方法调用可以干净地编译。目前尚不清楚您要达到什么目标,或者这对您来说是否足够好-但希望它可以解释为什么您会遇到错误...

于 2012-11-18T10:03:24.823 回答
0

它的类型不安全(我认为,关闭这些警告以避免注释污染)

    Class<? extends C> x = D.class;
    B b = new B();
    A y = x.newInstance().m(b);
    A z = D.class.newInstance().m(b);

但它有效。

于 2012-11-18T10:03:38.813 回答