2011-12-27 17 views
1

私のインターフェイス定義未確認の変換の警告は

interface IStorage { 
    <T extends ICommon> Collection<T> find(String name, boolean isExact); 
} 

であり、これは実装

Storage implements IStorage { 
    Collection<IOrganization> find(String name, boolean isExact) { 
     //some code 
    } 
} 

IOrganizationがICommonのサブタイプです。

まだ変換されていない警告が表示されるのはなぜですか。

答えて

3

あなたはそれが書かれているとして、あなたのためのインターフェースはfind()ICommon

あなたの実装がICommon特定のサブクラスCollectionを返している。拡張Collectionの何かを返すことを指定しますこれは、コンパイラが理解できる限り、チェックされていない変換です。 Collectionに実際にICommonという別のサブクラスが含まれているとどうなりますか?

0

あなたがStorageを定義しながら、あなたはまだ方法findを定義(およびそれを使用していない)されているので、同じ署名をしてください:

Storage implements IStorage { 
    <T extends ICommon> Collection<T> find(String name, boolean isExact) { 
     //some code 
    } 
} 

を、あなたが実際にそのジェネリックメソッドを呼び出すときは、コンクリートの型パラメータを指定します。

をあなたは、あなたの一般的な方法で <T extends ICommon>で導入
Storage s = new Storage(); 
s.<IOrganization>find("hello world", true); 

しかし、パラメータの型Tを使用すると、パラメータリストに持っていないので、役に立ちません。

一般的な方法ではありません。しかし、何かが次のように:

interface IStorage { 
    public Collection<? extends ICommon> find(String name, boolean isExact); 
} 

//and 
class Storage implements IStorage { 
    public Collection<IOrganization> find(String name, boolean isExact) { 
     //some code     
    } 
} 

//or 
class Storage implements IStorage { 
    public Collection<? extends ICommon> find(String name, boolean isExact) { 
     //some code 
    } 
} 
1

あなたのインタフェースの目的は、ICommonの特定の要素が返されているものをクライアントが知ることができるようになりますString name, boolean isExactの引数を使用してfindメソッドを定義することである場合は(、そのので例えば、次へ変更

interface IStorage<T extends ICommon> { 
Collection<T> find(String name, boolean isExact); 
} 

実装:

クライアントはちょうど、あなたのインターフェイスの署名は以下である必要があり、 Collection<IOrganization>ではなく Collection<? extends ICommon>をつかむことができます

これは、特定の型がfindメソッドを介して返されることを宣言するインターフェイスを定義した点で異なります。以前は、ICommonまたは一部の未知のサブタイプが返されたとしか言えませんでしたICollectionにキャストしようとすると、コンパイラは常にこれを行うことができるかどうかを検証できませんでした(ICollectionではない実装を与えた場合、実行時にClassCastExceptionが発生する可能性があります)。

+0

である。ジェネリックインターフェイスを作成するのは妥当です。 –

0

<T extends ICommon> Collection<T> find(...のような一般的な方法を使用している場合は、発信者がTに必要なものを要求できることを意味します。つまり、特定のT(あなたがやりたがっていると思われるもの)を選択できるのではなく、そのようなタイプTで動作する必要があります。実証するために、あなたの一般的な方法は、呼び出し側が

IStorage obj = ...; 
Collection<SomeRandomClassImplementingICommon> foo = obj.find(...); 

を言うことができますが、それはタイプCollection<SomeRandomClassImplementingICommon>を返さないので、あなたのCollection<IOrganization> find(...方法は、上記と互換性がありません。

関連する問題