2017-02-01 10 views
3

こんにちは、私はJavaと再帰ジェネリックでワイルドカードを使用する質問があります。私は、次のインターフェイスJava再帰ジェネリックとワイルドカード

public interface Recursive<R extends Recursive<R>> {} 

と私は私がしたい、そのクラスでこの

public interface Base<R extends Recursive<R>> { 
    Use<R>[] getUses(); 
} 

のように見え、ベースのインタフェースを持っている今、再帰的なインターフェース

public interface Use<R extends Recursive<R>> {} 

を使用する別のintrfaceを持っていますそのようなワイルドカードを使用する派生クラスです。

public class Derived extends Base<Recursive<?>> { 
    Use<?>[] getUses(); 
} 

これは許可されていませんが、私のジェネリックタイプはすべて適切なものであると言うことができますか?

+1

あなたはあなたの派生クラスでやりたいのですか?あなたのコードはコンパイルされますか? –

+0

'Derived extends Base 'で十分です。 –

+0

しかし、私は生のタイプを使用しているので警告が表示されますが、この警告が表示されない場合は方法がありますか? – MZuenni

答えて

0

Baseの型パラメータの制約を満足しないという問題があります。問題はRecursive<?>Baseの型パラメータの制約を満たさないことです。

Base<R>を延長する場合は、Rに何かを指定する必要があります。Recursive<R>です。コンパイラがRecursive<?> extends Recursive< Recursive<?> >を見つけられないので、Recursive<?>は十分ではありません。

それは本当に未知のタイプのBaseを延長しても意味がありませんが、あなたはそれらの異種コレクションを宣言することができます:私たちはBase

public abstract class Base< R extends Recursive<R> > { 
    public abstract R[] foo(); 
} 
ようになります知っているあなたのコメントから

Collection< Base<?> > cb; // ok for some reason 
Collection< Base< Recursive<?> > > cbr; // not ok! 

各資格についてRを行うことができます。

public class Derived< R extends Recursive<R> > extends Base<R> { 
    @Override public R[] foo() { 
     return (R[])new Object[] { r1, r2 }; 
    } 
} 

あなたのコメントから、これがあなたの望むものであることは明らかではありません。特定のRDerivedにはどのようなものを使用したいのですか?

編集以下のコンパイル。これで十分だろうか?最初の投稿に変更するために調整

interface Recursive< R extends Recursive<R> > {} 
abstract class Base< R extends Recursive< ? extends R > > { 
    abstract public R[] foo(); 
} 
class Derived extends Base< Recursive<?> > { 
    public Recursive<?>[] foo() { return null; } 
} 

EDIT 2

あなたのサブクラス(バインド右に)入力する必要があり
interface Recursive< R extends Recursive<R> > {} 
interface Use< R extends Recursive< ? extends R > > {} 
abstract class Base< R extends Recursive< ? extends R > > { 
    abstract public Use<R>[] foo(); 
} 
class Derived extends Base< Recursive<?> > { 
    @Override public Use< Recursive<?> >[] foo() { return null; } 
} 
+0

は、Rの配列を返すべきメソッドであり、派生クラスでは2つの異なるオブジェクト与えられたインターフェイスを実装する...両方のスーパークラスは再帰的なので、私はarayを返そうとしています... – MZuenni

+0

派生クラスは私の場合、その時点でどのような値が配列iに属しているか知っているからではありません戻る必要があります。問題は、私が返そうとしている2つの値が異なるクラスであることです。だから私はこのような配列を返す必要があることを知っています: '再帰的な [] {}'しかし、どのパラメータは、再帰的な戻り値を返すときにメソッドを正しくオーバーライドするためにはジェネリックに挿入する必要がありますか? [] – MZuenni

+0

Doこれらの2つのタイプに共通のスーパークラスがありますか? –

0

が、そうでない場合、コンパイラは、ワイルドカードと主張することはできませんあなたのメソッドが返すものと同じタイプのです。これは必須です。

これを試してみてください:

public class Derived<R extends Recursive<R>> extends Base<R> { 
    Use<R>[] getUses(); 
} 
+0

私はすでに、指定された型のインタフェースを実装する – MZuenni