0

私はプロのJavaプログラマーではないので、この質問は簡単かもしれませんが、Webで答えを検索しましたが、これまでのところ何も見つかりませんでした。

Javaにジェネリッククラスがあるとしましょう。

public class C1 <T, U> {
  public /*TYPE*/ f(T t, U u) {  
    return t.g(u)
  }

問題は、この一般的な例の結果のタイプをどのように判断できるかということです。どういうわけか次のようなものを書くことは可能typeof(t.g(u))ですか?

4

3 に答える 3

3

は無制限のタイプであるt.g(u)ため、そのまま呼び出すことはできません。Tコンパイラが使用可能なメソッドを認識できるように、コンパイル時の制限を設定する必要があります。Objectそうしないと、コンパイラが推測できるのTはextendsだけなので、メソッドを呼び出すことしかできませんObject

たとえば、呼び出したいメソッドG<U>とのインターフェースがある場合:g

public interface G<U> {
    R g(U u);
}

次にT extends G<U>、それを指定します。これにより、を呼び出すことができますg()。そして今、あなたはのリターンタイプが何であるかを知っていますg():それはですR

public class C1<T extends G<U>, U> {
    public R f(T t, U u) {  
        return t.g(u)
    }
}

結果を型にg()依存させたい場合は、次のようにすることができます。TU

public interface G<T, U> {
    T g(U u);
}

public class C1<T, U> {
    public T f(G<T, U> g, U u) {  
        return g.g(u)
    }
}
于 2012-11-22T18:15:25.740 に答える
2

tメンバー関数を持つコンパイラーに通知するものがないため、コードはそのままではコンパイルされませんgT実際にメソッドを宣言した基本クラスまたはインターフェースを拡張するものとして、typeパラメーターを宣言する必要がありますg()。戻りタイプは、の戻りタイプになりgます(別のパラメトリックタイプの場合もあります)。

例えば:

public interface Foo<X, Y> {
    X g(Y u);
}

public class C1 <T extends Foo<X, U>, U, X> {
    public X f(T t, U u) {  
        return t.g(u);
    }
}

戻り型Xも汎用である場合は、クラスでその型の個別の型パラメーターを宣言する必要があることに注意してくださいC1C1または、単一のパラメーター化されたタイプ(たとえば、String× StringString)を均一に処理することを宣言することもできます。

public class C1 <T extends Foo<T, T>> {
    public T f(T t, T u) {  
        return t.g(u);
    }
}

他のバリエーションも可能です。

于 2012-11-22T18:13:43.233 に答える
0

tにメソッドgを強制する場合は、次のようにクラスを宣言する必要があります。

public class C1<T extends Ginterface, U extends SecInterface> {
}

このメソッドの戻り型は、Ginterfaceのg関数の戻り型になります。

于 2012-11-22T18:13:54.417 に答える