2017-05-04 108 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中延伸,但我暂时还没有发现.. 我也许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'是'ChildPair'的一个子类,它是'GrandChildPair'的子类,并且你希望方法需要'ChildPair',那么你的方法签名应该是:'public static V getValue (ChildPair _Pair,串K)' – Andreas

回答

1

编辑更新了哪些类是允许不是基于@ 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的所有*子类,我想你可以使用if(!_pair.getClass()。isAssignableFrom(ChildPair.class))'(或者像它那样)。 –

+0

哦,现在我明白了ole的评论,也许我会很少例外的过程,如果声明谢谢 –

1

只有几件事情需要让它工作。这是正确的getValue()

public static <K,V> V getValue (ChildPair<K,V> _pair, K k) { 
    if (k != _pair.getK()) return null; 
    else return _pair.getV(); 
} 
  • 你需要指定只有两种类型的参数,在开始KVstatic <K,V>
  • 输入参数可以简单地为ChildPair<K,V>,所以它会接受ChildPairGrandChildPair,但是,它会拒绝Pair
  • 我相信你要确保getValue(),k的第二个参数总是与该对中的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

感谢它有点不同,但它是有趣的灵活扩展类型和另一种约束方式 –