Java 我可以对数字基类进行算术运算吗?

Java 我可以对数字基类进行算术运算吗?,java,Java,我正在尝试用Java创建一个泛型类,该类将对数字执行操作。在以下示例中,添加如下所示: public class Example <T extends Number> { public T add(T a, T b){ return a + b; } } 公共类示例{ 公共T添加(T a,T b){ 返回a+b; } } 请原谅我的天真,因为我对Java泛型比较陌生。此代码无法编译,错误如下: 未为参数类型T,T定义运算符+ 我认为添加“ext

我正在尝试用Java创建一个泛型类,该类将对数字执行操作。在以下示例中,添加如下所示:

public class Example <T extends Number> {

    public T add(T a, T b){
        return a + b;
    }

}
公共类示例{
公共T添加(T a,T b){
返回a+b;
}
}
请原谅我的天真,因为我对Java泛型比较陌生。此代码无法编译,错误如下:

未为参数类型T,T定义运算符+


我认为添加“extends Number”后,代码就可以编译了。是否可以使用Java执行此操作,或者我必须为每种数字类型创建重写的方法?

数字没有与之关联的+运算符,也不能,因为没有运算符重载

不过那会很好


基本上,您要求java自动装箱一个数字的descedant,它恰好包括整数、浮点和Double,可以自动装箱并应用加号运算符,但是,可能有任意数量的数字的其他未知子代无法自动装箱,直到运行时才知道。(该死的擦除)

考虑一下
示例
+
如何处理这个问题?没有
add
或类似的
Number
或类似的
Integer


更糟糕的是考虑<代码>最终类FunkyNoto扩展号{怪异的东西,不添加OP…} /代码>< /P> < P>这有一个类似的问题,答案是你不能这样做。 您可以检查a和b是否是Long/Double/Integer/etc的实例,并将add委托给如下方法:

public Integer add(Integer a, Integer b) {
    return a+b; // this actually uses auto boxing and unboxing to int
}

你们需要为每一个扩展数字的类型创建一个,所以这并不可行。换句话说,不要对数值操作使用泛型。作为超类的数量非常有限。

您的问题实际上与泛型无关,而是与运算符、原语与对象以及自动装箱有关

想想这个:

public static void main(String[] args) {
    Number a = new Integer(2);
    Number b = new Integer(3);
    Number c = a + b;
}
以上内容无法编译

public static void main(String[] args) {
    Integer  a = new Integer(2);
    Integer b = new Integer(3);
    Number c = a + b;
}
上面的代码是可以编译的,但这仅仅是因为自动装箱(autoboxing)——这是Java 5中引入的一种黑客语法粘合剂,并且(在编译时)只适用于某些具体类型:例如int Integer

在幕后,Java编译器正在重写最后一条语句(“我必须取消X
a
b
以将求和运算符应用于原始数据类型,并将结果框起来以将其分配给对象
c
”),因此:


Java无法取消对
数字的装箱,因为它在编译时不知道具体类型,因此无法猜测其原始对应项。

是的,Nathan是正确的。如果你想要这样的东西,你必须自己写

public class Example <T extends Number> {
    private final Calculator<T> calc;
    public Example(Calculator<T> calc) {
       this.calc = calc;
    } 

    public T add(T a, T b){
        return calc.add(a,b);
    }
}

public interface Calculator<T extends Number> {
    public T add(T a, T b);
}

public class IntCalc implements Calculator<Integer> {
    public final static IntCalc INSTANCE = new IntCalc();
    private IntCalc(){}
    public Integer add(Integer a, Integer b) { return a + b; }
}

...

Example<Integer> ex = new Example<Integer>(IntCalc.INSTANCE);
System.out.println(ex.add(12,13));
公共类示例{
私人期末计算器;
公共示例(计算器计算){
this.calc=calc;
} 
公共T添加(T a,T b){
返回计算添加(a、b);
}
}
公共接口计算器{
公共T添加(T a,T b);
}
公共类IntCalc实现计算器{
public final static IntCalc INSTANCE=new IntCalc();
私有IntCalc(){}
公共整数加法(整数a,整数b){返回a+b;}
}
...
Example ex=新示例(IntCalc.INSTANCE);
系统输出打印项次(例如添加(12,13));

太糟糕了,Java没有类型类(Haskell)或隐式对象(Scala),这个任务将是一个完美的用例…

您可以这样做

    class Example <T extends Number> {
        public Number add(T a, T b){
            return new Double(a.doubleValue() + b.doubleValue());
        }
    }
类示例{
公共号码添加(T a、T b){
返回新的Double(a.doubleValue()+b.doubleValue());
}
}

即使java运行时库也有这个问题,大多数处理原语的方法都必须复制相同的功能


最快的选择是为一种类型编写代码,然后复制它并替换该类型以生成其他类型的方法。一个简短的脚本应该足以做到这一点。

“可能有任何数量的数字的未知后代无法自动装箱”,例如
biginger
bigdecimic
,它们都扩展了
number
。我想,如果number有.add(A,b).sub(A,b).mult(A,b)。。。我们可以简单地用这些来代替,所以使用泛型,可能是一个接口号,由IntegerHero实现,可以扩展一个类似Integer的类(因为我们不能扩展最终的类),可以这样做吗?如果你想做这类事情,可能想看看Scala或Groovy。它们具有运算符重载和特定于域的语言功能:)我不敢相信,即使在2020年,Java也没有提供包含内置的加法/减法/乘法/除法等操作的超类。我希望能够从一个类扩展,而不是整数、双精度等,数字运算是开箱即用的!
    class Example <T extends Number> {
        public Number add(T a, T b){
            return new Double(a.doubleValue() + b.doubleValue());
        }
    }