2017-11-20 10 views
2

これは愚かな質問かもしれませんが、私はいくつかの方法があるとしましょう。このメソッドは、ジェネリック型の戻り値の型を持つかもしれませんが、このメソッドが返すクラスを決定することを望みます。意味は、メソッドを呼び出す時には知られていません。例:クラスジェネリックス - 返すメソッドの型を決める

public <U> SomeWrappingClass<U> execute() { 
    if (..) return new SomeWrappingClass<Foo>(); 
    else return new SomeWrappingClass<Bar>(); 
} 

SomeWrappingClass c = obj.execute(); 
c.barMethod() // in case of SomeWrappingClass<Bar> returned 
c.fooMethod() // in case of SomeWrappingClass<Foo> returned 

私はそれが動作しないと思いますし、タイプはメソッドコールの時点で知られていなければなりません。たぶん、返されたオブジェクトのいくつかのメンバーを介してのみ、またはメソッドのパラメータとしてジェネリックでRunnableの呼び出しを介して?例えば

public SomeReturnObject execute() { 
    SomeReturnObject o = new SomeReturnObject(); 
    if (..) 
    o.returnObj = new SomeWrappingClass<Foo>(); 
    else 
    o.returnObj = new SomeWrappingClass<Bar>(); 
} 

今私が編集

SomeWrappingClass

の場合にo.returnObj.barMethod()を呼び出すことができます。それのでResultObjectがあまりにソリューションではありません、(ResultObject < T>のようなジェネリック医薬品を有する少なくともResultObject)それがないと同じ状況です).. ..何とかクラスを返さない限り、呼び出し元はクラスを知っていますが、呼び出し時に知らなければならないClass < T>のような、それは再び不可能です。

+1

'SomeWrappingClass 'を使用できますか? –

+0

私は返すものの中でメソッドを決めることができますか? – luky

+0

@luky は、呼び出し元が正確に何が返されるかを決して知ることができないことを意味します。 – Lino

答えて

2

ジェネリックのことは、実行時ではなくコンパイル時にのみ重要です。

コンパイル時にSomeWrappingClass<Foo>SomeWrappingClass<Bar>かどうかわからない場合は、両方の場合に一致する共通分母を宣言する必要があります。 Alexandreの提案SomeWrappingClass

また、FooとBarの共通のスーパークラスまたはインターフェイスがある場合は、SomeWrappingClass<? extends SuperFooBar>を使用できます。

もちろん、呼び出し元はSomeWrappingClass<Foo>またはSomeWrappingClass<Bar>であるかどうかはわかりません。コンパイル時でも実行時でもありません。だから、それがあなたの呼び出し元のロジックに違いがあるなら、あなたは彼が区別するための方法を提供しなければなりません(しかしそれは "コードのにおい"です)。

1つの追加の可能性:

はサブクラスFooWrappingClass extends SomeWrappingClass<Foo>BarWrappingClass extends SomeWrappingClass<Bar>を紹介し、これらのクラスのインスタンスを返します。次に、特定の動作をそこに置くことができます。

+1

これはインタフェースが存在する理由です。私は拡張する代わりにインターフェイスを提案します。 'インタフェースMyFooBarBaz {public void executeFooOrBarOrBaz();}' – Tschallacka

関連する問題