2011-12-20 8 views
9

私はちょうど私が理解していないものに遭遇しました。 2番目のループが正当なものである場合、各ループが合法的でない理由は何ですか?Javaジェネリックと戻り値の型

public interface SomeInterface<T> { 
    List<SomeNamedObject> getObjects(); 
    void doSomething(P1 p1, T p2); 
} 

public class SomeNamedObject { 
    private String text; 
} 

public class Clazz { 

    private SomeInterface someInterface; 

    ... 

    public void someMethod() { 
     // Error Type mismatch: cannot convert from element type Object to TestClass.SomeNamedObject 
     for (SomeNamedObject someNamedObject : someInterface.getObjects()) { 
      // This loop won't compile as the someInterface.getObjects returns just a List and not a List<SomeNamedObject> 
     } 

     // Warning Type safety: The expression of type List needs unchecked 
     // conversion to conform to List<TestClass.SomeNamedObject> 
     List<SomeNamedObject> objects = someInterface.getObjects(); 
     for (SomeNamedObject someNamedObject : objects) { 
      // This loop compiles 
     } 
    } 
} 
+0

バグではなく、消去と生のタイプの問題です。 – Stefan

+0

問題の内容がわかりません。実際のスタックトレース(最初の数行だけ)を投稿できますか?私はあなたのフルクラスを推測している "SomeInterface "が必要ですが、例は ""を必要としませんおそらくそこに何かがありますか? – Jay

+1

@Jay彼のsomeInterfaceの宣言はジェネリック型を指定しません。その後、Javaは生の型に戻り、メソッドのシグネチャは生のList(返答参照)を返します。彼はオブジェクトの割り当てに関する警告を述べたはずです。 – Stefan

答えて

18

は、そのジェネリック型パラメータを指定しないprivate SomeInterface someInterface変数インスタンスは、ジェネリック医薬品の使用はすべてsomeInterfaceのために無効になっているため。これは、someInterface.getObjects()List<SomeNamedObject>ではなく、生戻りタイプListがあることを意味します。これが最初の例がコンパイルされない理由です。

List<SomeNamedObject> objects = someInterface.getObjects()は、リストの明示的な型を入れています。型の安全性が保証されていないため、これを行うと警告が表示されます。これは、getObjects()がタイプパラメータなしのList getObjects()と定義されている場合に表示されるのと同じ動作です。

+0

これは元のタイプミスであるかもしれませんが、 'SomeInterface 'は返される 'List'のジェネリック型を指定するのに' T'を使用しません。 'SomeNamedObject'としてハードコードされています。したがって、インスタンス変数が型付けされていなくても、返された 'List'には影響しません。 –

+5

genericパラメータが 'someInterface'の宣言で指定されていない場合、' SomeInterface'の* all *ジェネリック型は 'T'に依存しなくても無視されます。 – mikej

+0

非常に興味深いですが、独特です。 –

3

2番目のループの前にオブジェクトにアサインすると、コンパイラの警告が表示されることに注意してください。

Type safety: The expression of type List needs unchecked conversion to conform to 
List<TestClass.SomeNamedObject> 

これは、何らかの理由でgetObjects()メソッドが非生成リストを返すと言っていたはずです。最初のループがコンパイルされない理由を説明します。

あなたの参照をgenerifyを忘れたので:あなたはそれをgenerifyいけない場合

private SomeInterface someInterface; 

すべてが宣言されたメソッドのシグネチャを含む、生タイプを使用します。それは

private SomeInterface<Object> someInterface; 

ような何かを一覧<SomeNamedObject> するのではなく、生のListオブジェクトを返します。そして、それが動作するべきであることを意味します。

関連する問題