2016-07-05 8 views
8

私はJavaで奇妙なことを発見し、それに関する多くの情報を見つけることができませんでした。次のコードを考えてみましょう:ジェネリックスと抽象メソッド

public class TestClass { 

    private static abstract class AbstractClass { 
     abstract List<? extends Object> getList(); 
     abstract Map<Long, List<? extends Object>> getMap(); 
    } 

    private static final class ConcreteClass extends AbstractClass { 
     @Override 
     List<String> getList() { 
      return null; 
     } 

     @Override 
     Map<Long, List<String>> getMap() { 
      return null; 
     } 
    } 
} 

コンパイラがgetMap()法上のエラーを示しています。

getMap() in ConcreteClass cannot override getMap() in AbstractClass 
    return type Map<Long, List<String>> is not compatible with Map<Long, List<? extends Object>> 

をしかし、同じエラーがgetList()方法のために存在していない、まだ私が仕事をしたりするか、両方の期待どちらも失敗する。どちらの場合も、オーバーライド方法はList<? extends Object>の代わりにList<String>のdelcaringです。誰かがこれを説明できますか?

答えて

10

なくMap<Long, List<String>>からMap<Long, List<? extends Object>>まで、List<String>からList<? extends Object>への暗黙の変換が存在するためです。

ワイルドカードタイプを使用していない限り、すべてのジェネリックタイプは不変です。 「外側」マップタイプのジェネリックタイプ引数にはワイルドカードがないため、正確に一致しないジェネリックタイプは取り込めません。

地図のタイプがMap<Long, ? extends List<? extends Object>>だった場合、期待どおりに動作します。

サブタイプの戻り値の型がスーパータイプのメソッドの戻り値の型に暗黙的に変換可能な場合のみ、サブクラスが別の戻り値の型を持つスーパータイプメソッドをオーバーライドまたは実装できます。 (Java 1.4以降ではうまくいかない場合は、型が正確に一致しないとコンパイル時エラーになります)

+0

(期限が過ぎても受け入れます) – lucasvw

+3

良い点、私は 'を追加したいですか? extends Object'は効果なしで '?'に置き換えることができます – Andrew

+2

@Andrew:確かに、同じ原則が 'Object'だけでなくワイルドカードの下限にも適用されます。 –

関連する問題