2017-05-04 1 views
2

개체 및 문자열을 가져 오는 제네릭 메서드 만들기.제네릭 메서드] Java에서 다중 형식 매개 변수를 확장

는 먼저이 같은에서 작동 ..

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

나는 그것이 메인 클래스

GrandChildPair<String, Integer> tst = new GrandChildPair<>("dd", 1); 
Integer result = Util.getValue(tst,"dd"); 

같이 작동하지만에 ... 바인딩 유형 childPair하지 그랜드 하나에 확장 싶어 어쩌면 생각 이걸 제한해라. 접근? GrandPildPair에서 ChildPair 라인을 woking하지 않을 때까지. 그래서, 방법 정의에 처음

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

을 시도했지만 네, 그래서 나는 여러 유형의 매개 변수가 자바 연장하지만 난 아직 .. I를 찾을 수없는 약 어쩌면 3 시간 동안 검색 한 바보였다 다른 단일 유형 유모차를 찾았습니다. 그러나 전체를 확장 할 수 없습니다. 일반 유형 (검색에 좋지 않을 수 있음)

내가 할 수 있는게 있습니까?

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

본인의 표기법을 이해할 수 없습니다. Child Sweeper

+0

''Pair'가'GrandPild'의 서브 클래스 인'ChildPair'의 서브 클래스이고 메소드가'ChildPair'를 요구하기를 원한다고 가정하면 메소드 서명은 다음과 같아야합니다 :'public static V getValue (ChildPair _pair, 문자열 K)' – Andreas

답변

1

편집 클래스가 OleV.V @에 따라 허용되지 않는 것에 체크를 업데이트했습니다.의 의견

난 당신이 깔끔하게 자바가 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()); 
     } 
    } 
} 

백분율

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'의 * 모든 * 서브 클래스를 금지하고 싶다면'if (! _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(); 
} 
  • 당신은 두 유형 매개 변수, 처음에 KV를 지정해야합니다.
  • 입력 매개 변수는 ChildPair<K,V> 일 수 있으므로 ChildPair 및 을 수락하지만 Pair은 거부됩니다.
  • getValue(), k의 두 번째 매개 변수는 항상 해당 쌍의 K과 동일한 유형이어야합니다. 따라서 저는 K k으로 지정했습니다.extends : public static <K,V,K2 extends K> V getValue (ChildPair<K,V> _pair, K2 k)으로 더 유연하게 만들 수 있습니다.

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

    이 너무 :

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

    이 작동됩니다 설계된대로

그래서이 거부됩니다

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

덕분에 조금 다르지만 재미있는 유연한 확장 유형과 또 다른 바운드 방식이다. –

관련 문제