2016-06-29 37 views
0

親と子の2つのクラスを作成しました。 「クラスの親がComparableを実装する」と 私の親クラスはタイプパラメータのワイルドカードを使用する余分なキャストが必要

をComparableインタフェース を実施している私も、私はここで 、リストの最大の要素を返すメソッドを持って書かれていますか?スーパーTワイルドカードは、親の子クラスを受け入れる。

次のコードは、子オブジェクトの一覧で正常に動作します。

public static <T extends Comparable<? super T>> T max(List <T> list){ 
    Iterator< T> itr = list.iterator(); // line xx 
    T result = itr.next(); 
    T temp ; 
    while(itr.hasNext()){ 
     temp = itr.next(); 
     if(temp.compareTo(result) > 0) 
      result = temp ; 
    } 
    return result ; 
} 

しかし、私は<を使用してTのサブタイプのいずれかのリストを受け入れるために、最大の方法のプロトタイプを変更した場合は? extends T> 上記のコードはコンパイルされません。

コンパイルにエラーは、次のとおりにラインxxを変更に

をイテレータイテレータへ変換することができない "イテレータ< T> ITR =(イテレータ)list.iterator();"コードは<で動作しますか? T>引き数を拡張します。

public static <T extends Comparable<? super T>> T max(List <? extends T> list){ 
    Iterator< T> itr = (Iterator<T>) list.iterator(); // works fine 
    Iterator< T> itr1 = list.iterator();   // generates compile error . 
    T result = itr.next(); 
    T temp ; 
    while(itr.hasNext()){ 
     temp = itr.next(); 
     if(temp.compareTo(result) > 0) 
      result = temp ; 
    } 
    return result ; 
} 

私はコンパイル時のエラーがスローされる理由を知りません。

完全なコードは以下の通り:

package Generics; 

import java.util.*; 

public class WildCard { 
public static void main(String[] args) { 
    List<Child> cList = Arrays.asList(new Child("c1"),new Child("c3"),new Child("c2")); 
    System.out.println(max(cList)); 
} 

public static <T extends Comparable<? super T>> T max(List <? extends T> list){ 
    Iterator< T> itr = (Iterator<T>) list.iterator(); 
    T result = itr.next(); 
    T temp ; 
    while(itr.hasNext()){ 
     temp = itr.next(); 
     if(temp.compareTo(result) > 0) 
      result = temp ; 
    } 
    return result ; 
} 
} 
class Parent implements Comparable<Parent>{ 
    private String val ; 
    public Parent(String val){ 
     this.val = val ; 
    } 
    @Override 
    public int compareTo(Parent o) { 
     // TODO Auto-generated method stub 
     return this.val.compareTo(o.val); 
    } 
    public String toString(){ 
     return val ; 
    } 
} 
class Child extends Parent{ 

    public Child(String val) { 
     super(val); 
    } 

} 

私の疑問は、私が使用していなかった場合でも、ありますか?関数の引数にTを拡張します。 サブタイプを受け入れることができました。キャストは必要ありませんでした。 しかし、なぜその構文を変更するには私は型キャスティングが必要ですか?

+0

私は答えはありませんが、キャストを避けるために使用できる2つのテクニックがあります。 for-eachループはキャストを必要としないので、 'for(T t:list)'を使うことができます。また、イテレータでワイルドカードを使用して、キャストを避けることもできます: 'Iterator itr = list.iterator();'。 – DavidS

答えて

0

あなたはList<? extends T>を持っているので、あなたはIterator<? extends T>を使用する必要があります。

Iterator<? extends T> itr = list.iterator(); 

そしてIteratorとにかくTのプロデューサーであるので、PECSルールに従って(プロデューサーextends、消費者super)ので、それは当然ですとにかくはextendsである必要があります。

関連する問題