泛型方法]在JAVA中扩展多个类型参数

时间:2017-05-04 06:51:16

标签: java generics type-parameter

我正在制作一个获取对象和字符串的通用方法。

它最初像这样工作..

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而不是Grand ... 限制这个..access?直到ChildPair线,而不是在GrandChildPair中。 所以我先尝试过方法定义,

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

但是,它是愚蠢所以我搜索了大约3个小时关于多个类型参数扩展在java但我还没有找到.. 我发现其他单一类型的婴儿车扩展了例子,但我找不到扩展整体 泛型(可能不擅长搜索..)

我能做什么?

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);

    }
}

2 个答案:

答案 0 :(得分:1)

编辑根据 @ OleV.V。的评论更新了对不允许的课程的检查

我认为你不能干净地强制该方法不接受GrandChildPair作为参数,因为java认为它是ChildPair的类型,也是Pair。我也认为如果你必须这样做,那么这些关系可能需要重新设计,因为这不是正确的方法。

有一个不太好的方法:

主要

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 :(得分: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);