8

次のクラスがあるとします。

public class Either<A, B> {
    public Object get();
}

Eitherは、タイプ A または B のいずれかのオブジェクトを 1 つ格納するタイプです get()。その 1 つのオブジェクトを取得します。

get()問題は、返される型が だけでなく、A と B の共通のスーパータイプになるように、ジェネリックを使用して のメソッド シグネチャを変更できるかどうかですObject。たとえば、 anEither<Integer, Long>get()returnを持つことができNumber、 anEither<Deque<T>, Set<T>>get()returnIterable<T>またはCollection<T>を持つことができます。等々。(明らかに、 an にEither<Foo,Foo>get()returnが必要Fooです)。

これが可能な場合、私が持っていた場合Either<List<A>, List<B>>、最も具体的な型は何get()を返すことができますか? raw List、 wildcard List<?>、またはまったく別のものですか?

4

4 に答える 4

2

Java推論にも似たようなものがあります。

public static <C, A extends C, B extends C> C get(Either<A,B> e)
{   return (C)e.get();    }

inference:

    A=Integer, B=Long    ==>    C=Number

    A=List<Integer>, B=List<Long>      ==>   C=List<? extends Number>

usage:

    Either<Integer, Long> x = ...;
    get(x); // the return type is Number

ただし、それをインスタンスメソッドに変換する方法はおそらくありません。書く必要があります

public class Either<A,B>

    public <C super A|B> C get() { ... }

or simply

    public A|B get(){ ... }

これはJavaではサポートされていません

于 2012-09-01T22:28:51.497 に答える
1

必要と思われるだけAとBに共通のロジックを含む抽象クラスCを定義し、Eitherクラスでそれを参照してみませんか。

public class Either<C> {
    public C get();
}

それはあまり答えのようには思えませんが、Javaはコンパイル時にとにかく型情報を消去するので(つまり、コンパイルされたコードはまたはObjectの代わりにのみ表示されAますB)、あなたは何をすべきかを定義するのに最適な立場にあります明示的な共通クラスに保持されます。

于 2012-09-01T18:20:34.413 に答える
1

私の知る限り、それは不可能です: あなたのクラスは、 A と B の両方が拡張Either<A,B>するジェネリックな 3 番目の型 ( と呼びましょう) について仮定します: のようなものを書くことは可能ですが、Java は forward を許可しません-ジェネリック型を参照しているため、 のようなものを書くことさえできません。あなたのクラスは本当に便利なので、明らかに残念です:)Cpublic class Either<A extends MyNonFinalClass, B extends MyNonFinalClass> {}Either<A extends C, B extends C, C>Either

于 2012-09-01T19:44:26.247 に答える
1

A と B が共通の祖先を共有していることを確認する必要があります。

public class Either<A extends CommonAncestor, B extends CommonAncestor> {
    public CommonAncestor get() {....}
}

また

public class Either<C, A extends C, B extends C> {
    public C get() {....}
}
于 2012-09-01T21:46:04.080 に答える