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.
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).
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. 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.
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. 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. 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). 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
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:
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());
}
}
精彩评论