1

class MyClass<E>2 つの型パラメーターを持つ 2 つ目のジェネリック クラスのクラス変数を持つ、1 つの型パラメーターを持つジェネリック クラスを作成しようとしていますSecondClass<V, E>。私のコードでは、 の型が何であるかは実際には問題ではないのでV、その変数の型を として宣言しますSecondClass<?, E> var。MyClass の実装のある時点で、V, を返す var のメソッドを呼び出し、Vpublic V foo(E e)型のこのオブジェクトを var, の別のメソッドに渡しますpublic int bar(V v)。ただし、これは漠然としか理解できない理由でコンパイルされませんが、hereで説明されていると思います。

どうやら、キャプチャー・オブ・?foo によって返されるのは、capture-of-? とは異なります。バーによって要求されます。しかし、なぜ?V の実際の型が何であれ、同じインスタンスで呼び出されるため、両方のメソッドで同じでなければなりません。ここで何が欠けていますか?

最終的に、私が知りたいのはこれです: MyClass の型パラメーターに V を追加せずにコードをコンパイルするには、何を変更する必要がありますか? (問題にならないので、 MyClass のユーザーに V のタイプを指定するよう強制したくありません)


より具体的な例を示すために、私が取り組んでいることの単純化されたバージョンを次に示します。型パラメータからすでに推測できるように、これはグラフに関するものです。MyClassに変換しEdgePainter、 にSecondClass変換しGraphます。このコードでは、コンパイル エラーは の最初の行にありEdgePainter.getColor(E)ます。

class Graph<V, E>
{

    public V getTarget(E edge)
    {
        return null;
    }

    public int getInDegree(V vertex)
    {
        return 0;
    }

}

class EdgePainter<E>
{

    private static final Color COLOR_FOR_MANY_EDGES = Color.RED;
    private static final Color COLOR_FOR_FEW_EDGES = Color.BLUE;

    private Graph<?, E> graph;

    public EdgePainter(Graph<?, E> aGraph)
    {
        graph = aGraph;
    }

    public Color getColor(E edge)
    {
        // My compiler says:
        // The method getInDegree(capture#3-of ?) in the type
        // Graph<capture#3-of ?,E> is not applicable for the arguments
        // (capture#4-of ?)
        int degree = graph.getInDegree(graph.getTarget(edge));
        if (degree > 10)
            return COLOR_FOR_MANY_EDGES;
        else
            return COLOR_FOR_FEW_EDGES;
    }

}
4

1 に答える 1

3

ジェネリック メソッドを呼び出すことで、ワイルドカードを取得できます。

public Color getColor(E edge) {
    return getColorInternal(graph, edge);
}
private <X> Color getColorInternal(Graph<X, E> g, E e) {
    int degree = g.getInDegree(g.getTarget(e));
    // ...
}

これは典型的なシナリオです。実装には型引数が必要ですが、API ユーザーから隠したいと考えています。多くのメソッドが影響を受ける場合は、別の、おそらくネストされた class を定義すると便利EdgePainterInternalです。この内部実装には 2 番目の型パラメーターがGあり、公開されている実装はすべての呼び出しを のインスタンスにEdgePainter委任します。EdgePainterInternal

于 2013-02-12T13:40:31.110 に答える