Reputation: 3070
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?
Upvotes: 3
Views: 5349
Reputation: 418
For Addition we can use doubleValue()
method of Number
class. To return the same type value, the idea is to use a Function
or Supplier
or a Factory
to create instances of the type T.
class MathOperation<T extends Number> {
public double add(T a, T b) {
double d = a.doubleValue() + b.doubleValue();
return d;
}
public T add(T a, T b, Function<Double,T> function) {
double d = a.doubleValue() + b.doubleValue();
return function.apply(d);
}
}
Upvotes: 1
Reputation: 14159
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.
Upvotes: 0
Reputation: 28752
+
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 (....)
}
}
Upvotes: 4