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 に答える