I've made an interface of math operation with one method, calculate, taking various number of arguments
public interface MathOperation {
public <T extends Number> T calculate(T... args);
}
There's also simple implementation of this class, which does not work:
private class Sum implements MathOperation {
@Override
public <T extends Number> T calculate(T... args) {
return args[0] + args[1];
}
}
The problem is:
bad operand types for binary operator '+'
first type: T
second type: T
where T is a type-variable:
T extends Number declared in method <T>calculate(T...)
What I'm trying to achieve is a simple class, taking for example two Doubles and returning Double as well.
Is there possibility to achieve this?
+
cannot be applied to types that extend Number
. new Integer(5) + new Integer(5)
works because of autoboxing. You will have to look at the runtime type of args and do the operation accordingly.
Something on the lines of:
private class Sum implements MathOperation {
@Override
public <T extends Number> T calculate(Class<T> clazz, T... args) {
if (clazz.equals(Integer.class))
{
return Integer.class.cast(args[0]) + Integer.class.cast(args[1]);
} else (....)
}
}
You can test the runtime type as shown in the other answers. Or you can try a different design: Create an abstract class that works as a factory:
interface MathContext<T extends Number> {
...
T valueOf(double d);
T valueOf(int i);
T add (T... args);
}
And concrete classes for the types that you want to use:
DoubleContext implements MathContext<Double> {
...
Double valueOf(int i) {
return i;
}
Double valueOf(double d) {
return d;
}
Double add(Double... args) {
Double res = 0;
for (Double arg: args) {
res += arg;
}
return res;
}
}
Now you could implement your MathOperation using that class. However, it's not really needed any more.