2017-05-04 12 views
2

オブジェクトと文字列を取得する一般的なメソッドを作っています。ジェネリックメソッド] Javaの複数型パラメータを拡張

それは、このように最初で働いています。..

public static <K, V> V getValue(Pair<K,V> _pair, String k){ ... } 

へ ..私は多分それはメインクラスのように

​​

を働くと思った。しかし、私はバインドタイプがchildPairグランドないものに拡張したいですこれを制限する? ChildPairの行まで、GrandChildPairでそれを起動しないでください。 ので、私は、メソッド定義の最初の

public static <K extends ChildPair<K,V>, V extends ChildPair<K,V> V getValue (

を試してみたが、はい、それは私が複数の型パラメータは、Javaに延びているが、私はまだ.. Iが見つかりませんでした程度多分3時間検索したダムでした他のシングルタイプのpramが例を拡張するのを見つけましたが、私は全体を拡張することができません ジェネリックタイプ(検索にはあまり良くないかもしれません)

私は何ができますか?

public class Util { 

    ///define method 
    ////   //Type parameters //return type// method name (prams...) { 
    public static (Pair extends ChildPair) V getValue (Pair<K,V> _pair, String k) { 

     if (k != _pair.getK()) return null; 
     else return _pair.getV(); 
    } 
} 

public class Pair<K, V> { 
    private K k; 
    private V v; 

    Pair(K k, V v) { 
     this.k = k; 
     this.v = v; 
    } 

    public K getK() { 
     return k; 
    } 
    public V getV() { 
     return v; 
    } 
} 

public class ChildPair<K, V> extends Pair<K, V> { 
    public ChildPair(K k, V v) { 
    super(k, v); 
    } 
} 

public class GrandChildPair<K, V> extends ChildPair<K, V> { 

    public GrandChildPair(K k, V v) { 
     super(k, v); 
    } 
} 

public class Main { 

    public static void main(String[] args) { 
     Pair<String, Integer> pair = new Pair<>("someone", 35); 
     Integer age = Util.getValue(pair, "someone"); 
     System.out.println(age); 

     ChildPair<String, Integer> childPair = new ChildPair<>("gh", 20); 
     Integer childAge = Util.getValue(childPair, "sss"); 
     System.out.println(childAge); 

    } 
} 
+0

これを正しく読んでいるならば、ワイルドカードの境界線は必要ありません。引数を 'ChildPair 'にしてください。 – yshavit

+0

私は本当にあなたの表記を理解していません、子 Sweeper

+0

'' Pair''が 'GrandChildPair'のサブクラスである' ChildPair'のサブクラスであり、メソッドに 'ChildPair'が必要な場合、メソッドのシグネチャは' public static V getValue (ChildPair _pair、文字列のk) ' – Andreas

答えて

1

EDITがOleV.V @に基づいて許可されていませんどのようなクラスのチェックを更新しました。のコメント

私はあなたがきれいはJavaがChildPairともペアの種類として、それを考慮するためのパラメータとしてGrandChildPairを受け入れないようにする方法を強制することができるとは思いません。また、これをやらなければならない場合、これらの関係を再設計する必要があるかもしれないと考えています。これは正しい方法ではないからです。

行くには非常に良いではない方法があります:

メイン

public class Main { 

    public static void main(String[] args) { 
     try { 
      // works 
      Pair<String, Integer> pair = new Pair<>("someone", 35); 
      Integer age = (Integer) Util.getValue(pair, "someone"); 
      System.out.println(age); 
     } catch (Exception e) { 
      System.out.println("error: " + e.getMessage()); 
     } 

     try { 
      // mismatch in K so returns null 
      ChildPair<String, Integer> childPair = new ChildPair<>("ch", 20); 
      Integer childAge = (Integer) Util.getValue(childPair, "sss"); 
      System.out.println(childAge); 
     } catch (Exception e) { 
      System.out.println("error: " + e.getMessage()); 
     } 

     try { 
      // error 
      GrandChildPair<String, Integer> grandChildPair = new GrandChildPair<>("gh", 40); 
      Integer grandChildAge = (Integer) Util.getValue(grandChildPair, "gh"); 
      System.out.println(grandChildAge); 
     } catch (Exception e) { 
      System.out.println("error: " + e.getMessage()); 
     } 

     try { 
      // error 
      OtherChildPair<String, Integer> otherChildPair = new OtherChildPair<>("oh", 60); 
      Integer otherChildAge = (Integer) Util.getValue(otherChildPair, "oh"); 
      System.out.println(otherChildAge); 
     } catch (Exception e) { 
      System.out.println("error: " + e.getMessage()); 
     } 
    } 
} 

Utilの

public class Util { 

    public static Object getValue(Pair<?, ?> _pair, String k) throws Exception { 
     // check specific class and return/throw error 
     // if (_pair instanceof GrandChildPair) { 

     // OR check if it extends ChildPair and return/throw error 
     if (_pair.getClass().isAssignableFrom(ChildPair.class) == false) { 
      throw new Exception("call not allowed"); 
     } 

     if (_pair.getK().equals(k) == false) { 
      return null; 
     } 

     return _pair.getV(); 
    } 
} 

OtherChildPair

public class OtherChildPair<K, V> extends ChildPair<K, V> { 

    public OtherChildPair(K k, V v) { 
     super(k, v); 
    } 
} 

出力

35 
null 
error: call not allowed 
error: call not allowed 
+1

あなたは* ChildPair' 'のすべて*サブクラスを禁止したい場合、私はあなたが'(もし!_pair.getClass()。isAssignableFrom(ChildPair.class)) '(またはそれのようないろいろ書い)を使用するかもしれないと思います。 –

+0

ああ今、私はoleのコメントを理解している可能性があります。if文のおかげで少し例外的な処理になります。 –

1

動作させるために必要なものはいくつかあります。これは右のgetValue()です:static <K,V>

public static <K,V> V getValue (ChildPair<K,V> _pair, K k) { 
    if (k != _pair.getK()) return null; 
    else return _pair.getV(); 
} 
  • あなたは2つだけ型パラメータ、初めにKVを指定する必要があります。
  • 入力パラメータは単にChildPair<K,V>にすることができるので、ChildPairとを受け入れますが、それはPairを拒否します。
  • getValue()kの2番目のパラメータは、必ずペアのKと同じタイプになります。したがって私はK kと指定しました。extendspublic static <K,V,K2 extends K> V getValue (ChildPair<K,V> _pair, K2 k)を使用すると、柔軟性を高めることができます。

設計されて、これは、拒否されます。

Pair<String, Integer> pair = new Pair<>("someone", 35); 
Integer age = Util.getValue(pair, "someone"); // compiler error 

これは動作します:

ChildPair<String, Integer> childPair = new ChildPair<>("gh", 20); 
Integer childAge = Util.getValue(childPair, "sss"); 
System.out.println(childAge); 

あまりにもこの:

ChildPair<String, Integer> grandChildPair = new GrandChildPair<>("gh", 20); 
Integer childAge = Util.getValue(childPair, "sss"); 
System.out.println(childAge); 

そして、あまりにもこの:

GrandChildPair<String, Integer> grandChildPair = new GrandChildPair<>("gh", 20); 
Integer childAge = Util.getValue(childPair, "sss"); 
System.out.println(childAge); 
+0

おかげさまで少し感謝していますが、 –

関連する問題