简体   繁体   English

如何在 Java 中使用 generics 与语言运算符和通用 class 扩展编号

[英]how to use generics in Java with language operators and generic class extending Number

I would like to perform an operation on two generics argument of the same type both extending Number.我想对两个相同类型的 generics 参数执行一个操作,它们都扩展了 Number。

Is it Possible?可能吗? I always used to call methods on generic arguments, but seems there is some problem using operators (The operator + is undefined for the argument type(s) T, T).我总是习惯于在通用 arguments 上调用方法,但使用运算符似乎存在一些问题(对于参数类型 T、T,运算符 + 未定义)。

public static <T extends Number> T sum(T a, T b){
    return a+ b;
}

What am I doing wrong?我究竟做错了什么?

EDIT: I try to improve a little bit my question.编辑:我尝试改进一点我的问题。 I understood that operators are not defined for type Number.我知道没有为 Number 类型定义运算符。 It's a bit sad this thing because it would be nice to perform such an operation without introducing new interfaces like suggested by @Victor Sorokin.这件事有点可悲,因为如果不引入@Victor Sorokin 建议的新接口,执行这样的操作会很好。

But I still don't understand one thing: if operators are not implemented in the class Number, then at least in Double class should be implemented because I can use + operator with double.但是我仍然不明白一件事:如果 class 号中没有实现运算符,那么至少应该在 Double 中实现 class 因为我可以使用 + 运算符和 double。 Neither these line of code will compile:这些代码行都不会编译:

public static <T extends Double> T sum(T a, T b){

    T c = a +b;
}

why?为什么?

It's not possible because Number doesn't have a + operator associated with it.这是不可能的,因为Number没有与之关联的 + 运算符。 In particular, you can't do this:特别是,您不能这样做:

Number a = new Integer(1);
Number b = new Integer(2);
Number c = a + b;

There is no + operator for classes in Java (except String and there's implicit conversion for other types via toString() when one of arguments is String). Java 中的类没有+运算符(String 除外,当 arguments 之一是 String 时,通过toString()对其他类型进行隐式转换)。 So, make you type implement some interface, say所以,让你输入一些接口,比如说

interface Valuable {
    // use richest built-in numeric type
    double value();
    Valuable value(double v);
}

public static <T extends Valuable> T sum(T a, T b){
    return a.value(a.value() + b.value());
}

Ugly, isn't it?丑陋,不是吗? =D =D


Fix 2022 code above is wrong, as Valuable#value can't produce instance of subtype T , so we need to go a bit more hairy:修复上面的 2022代码是错误的,因为Valuable#value不能产生子类型T的实例,所以我们需要 go 多毛一点:

interface Valuable<T extends Valuable<T>> {
    // use richest built-in numeric type
    double value();
    T value(double v);
}

class Impl implements Valuable<Impl> {
    private final double v;

    Impl(double v) {
        this.v = v;
    }

    @Override
    public double value() {
        return v;
    }

    @Override
    public Impl value(double v) {
        return new Impl(v);
    }

    @Override
    public String toString() {
        return "Impl{" +
                "v=" + v +
                '}';
    }
}

class Scratch {

    public static void main(String[] args) {
        Impl a = new Impl(1), b = new Impl(-1);
        System.out.println(a + " + " + b + " = " + sum(a, b));
    }

    public static <T extends Valuable<T>> T sum(T a, T b){
        return a.value(a.value() + b.value());
    }
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM