为什么这种类型的通配符不起作用?

时间:2012-11-18 09:29:21

标签: java generics

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)

2 个答案:

答案 0 :(得分: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>实现X实现{ {1}}。怎么会知道那是A

如果您想致电B,则需要m(b),这意味着您的申报需要

C<B>

此时,方法调用干净地编译。目前还不是很清楚你想要达到的目标,或者这对你来说是否足够好 - 但希望它能解释为什么你得到的错误......

答案 1 :(得分:0)

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

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

但它确实有效。