I have read several pages on generic methods and have some sort of grasp on them, but I still don't understand them. So say I have a method to multiply two numbers and return the product:
public double multiply(SomeNumberVariableType x, SomeNumberVariableType y){
return x * y;
}
How can I use bounded generics to have only a number type permitted as parameters?
Maybe this is your intention:
public static <N extends Number> double multiply(N x, N y){
return x.doubleValue() * y.doubleValue();
}
Although I must also say that the generic use of Number instead of concrete immutable value types like java primitive double is probably not so healthy because in the example above the arguments could even be of different types, for example Integer and Double.
Attention:
I confirm, the arguments can be of different types as given signature above. So the answer of Bohemian is wrong. I have tested it just now (but knew it already before). The compiler only guarantees that both arguments are of type Number, nothing else.
In order to assert the same argument types the compiler needs self-referencing generics. This feature is not fulfilled by Number-class (that is <N extends Number<N>> is unfortunately not possible). That is why I consider the whole Number approach as not really healthy. Here a test code which everyone can execute:
Integer x = Integer.valueOf(10);
Double y = new Double(2.5);
System.out.println(multiply(x, y));
// Output: 25.0
In general, Java generics are not appropriate for math.
In Java:
It looks like you can perform math on objects because you can do something like this:
Integer a = 1;
Integer b = 2;
Integer c = a + b;
But that is only due to autoboxing. What actually happens is the compiler replaces that code with this:
Integer a = new Integer(1);
Integer b = new Integer(3);
Integer c = Integer.valueOf(a.intValue() + b.intValue());
With generics you can specify a bound so that your type must be Number or a subtype of it:
static <N extends Number> N multiply(N n1, N n2) {
return n1 * n2; // but you cannot do this because the type is not known
// so the compiler cannot do autoboxing
}
If a supertype is known, you can call methods on them so you can do this as has been pointed out:
static <N extends Number> double multiply(N n1, N n2) {
return n1.doubleValue() * n2.doubleValue();
}
But that is no different than the following:
static double multiply(double n1, double n2) {
return n1 * n2;
}
Except that the generic version can, for example, take BigDecimal as an argument which will of course not provide a reliable result (see BigDecimal#doubleValue). (Neither will Long for that matter.)
If you were really determined you could program your own number classes and use polymorphism. Otherwise use overloads or (best of all) stick to one type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With