简体   繁体   English

如何将方法限制为仅接受具有特定限制的参数?

[英]How can I limit a method to only accept parameters with certain restrictions?

I have the following Duple class, and I'm trying to write methods to perform math over both of its "cells" ((new Duple(1,2)).plus(new Duple(2,6) == new Duple(3,8)) : 我有以下Duple类,并且我正在尝试编写在两个“单元格”上执行数学运算的方法((new Duple(1,2)).plus(new Duple(2,6) == new Duple(3,8))

final class Duple<T,U> {
    final T a;
    final U b;
            public Duple(T a, U b) { this.a = a; this.b = b; }

    public String toString() {
        return "(" + a + ", " + b + ")";
    }

    /*public Duple<T,U> plus(Duple <T,U> otherDuple) {
        return Duple(a + otherDuple.a, b + otherDuple.b);
    }*/

The commented-out code gives an error because it can't guarantee that T or U will support + . 注释掉的代码给出了错误,因为它不能保证TU将支持+ Is there a way to have it do a compile time check on the parameters? 有没有一种方法可以对参数进行编译时检查?

I tried: 我试过了:

public Duple<T,U> plus(Duple <T extends Number,U extends Number> otherDuple) { ... }

But the compiler complains for me to delete extends . 但是编译器为我抱怨删除extends I saw an example using a user defined interfaces, but for what I need it for, that seems extreme. 我看到了一个使用用户定义的接口的示例,但是对于我需要的接口,这似乎很极端。

Basically I'm trying to emulate: 基本上,我试图模仿:

plus :: (Num t, Num u) => Duple t u -> Duple t u -> Duple t u
(x1,y1) `plus` (x2,y2) = (x1 + x2,y1 + y2)

If it were written in Haskell 如果是用Haskell编写的

You cannot have a method that only exists on some instantiations of your class. 您不能拥有仅存在于类的某些实例中的方法。

Instead, you can put the constraints on the class's type parameters. 相反,您可以将约束放在类的类型参数上。

There really isn't a good way to do this in Java; 在Java中,确实没有很好的方法来执行此操作。 the language doesn't support any kind of "add" or "plus" function that will work on any arbitrary subclass of Number . 该语言不支持在Number任意子类上均可使用的任何类型的“ add”或“ plus”功能。

However, I've found a rather hack-ish way to work around it. 但是,我发现了一种解决该问题的方法。 It requires that you set up a map that maps each numeric class you're interested in to a function that will add two numbers of that class, and then looking up the function at runtime. 它要求您设置一个映射,将您感兴趣的每个数字类映射到一个将对该类添加两个数字的函数,然后在运行时查找该函数。 This uses Java 8: 这使用Java 8:

final class Duple<T,U> {
    final T a;
    final U b;
    public Duple(T a, U b) { this.a = a; this.b = b; }

    public String toString() {
        return "(" + a + ", " + b + ")";
    }

    private static Map<Class,BinaryOperator> adders = new HashMap<>();

    private static <T> void setAdder(Class<T> forClass, BinaryOperator<T> adder) {
        adders.put(forClass, adder);
    }

    private static void setAdders() {
        setAdder(Integer.class, (x, y) -> x + y);
        setAdder(Long.class, (x, y) -> x + y);
        setAdder(Float.class, (x, y) -> x + y);
        setAdder(Double.class, (x, y) -> x + y);
        setAdder(BigInteger.class, (x, y) -> x.add(y));
        // add more as desired
    }

    static {
        setAdders();
    }

    private static <T1> T1 add(T1 x, T1 y) {
        BinaryOperator adder = adders.get(x.getClass());
        if (adder == null) {
            throw new RuntimeException("No plus operation defined for class");
        }
        return (T1)adder.apply(x, y);
    }

    public Duple<T,U> plus(Duple <T,U> otherDuple) {
        return new Duple(add(this.a, otherDuple.a), add(this.b, otherDuple.b));
    }

}

My test program: 我的测试程序:

public static void main(String[] args) {
    Duple<Long,Double> x1, x2, x3;
    Duple<Float,BigInteger> x4, x5, x6;
    x1 = new Duple<>(3L, 4.0);
    x2 = new Duple<>(6L, 2.2);
    x3 = x1.plus(x2);
    System.out.println(x3);

    x4 = new Duple<>(1.7F, BigInteger.valueOf(15));
    x5 = new Duple<>(3.1F, BigInteger.valueOf(22));
    x6 = x4.plus(x5);
    System.out.println(x6);
}

and the output is what you'd expect: 输出是您期望的:

(9, 6.2)
(4.8, 37)

(This uses some raw types, but I don't know of a way around that.) (这使用了一些原始类型,但是我不知道如何解决。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以将方法参数限制为仅某些Enum成员吗? - Can I restrict method parameters to only certain Enum members? 如何简化使用某些参数而不使用其他参数调用方法的验证? - How can I simplify verification that a method is called with certain parameters and no others? 如何在Struts2中强制方法仅接受POST参数? - How to force a method to only accept POST parameters in Struts2? 如何修改我的代码以只接受某种数据类型? - How can I modify my code to only accept a certain data type? 如何强制Java为方法调用的参数之一接受条件类型? - How can I force Java to accept a conditional type for one of the parameters of a method call? 如何中断 ServerSocket accept() 方法? - How can I interrupt a ServerSocket accept() method? 如何使接口实例方法仅接受同一类的参数? - How can I make an interface instance method accept arguments of the same class only? 我怎样才能使接口实例方法只接受同一个类的参数,真的吗? - How can I make an interface instance method accept arguments of the same class only, really? 如何允许泛型类方法仅由某些类型的参数执行? - How to allow a generic class method to be executed only by certain types of parameters? 如果我只能获取某个类的对象,而我的方法只能在 sublass 上工作,如何避免 instanceof - How to avoid instanceof if I can only obtain objects of a certain class, but my method can only work on the sublass
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM