Reputation:
I want to write a generic method in java like below:
public <T extends Number & Comparable<T>> void test(T[] a){
T b=a[0];
if(a[0]>0){
a[0]*=a[0];
b+=a[1];
}
}
Then later, I can supply either Integer[]
or Double[]
or other Number
subtypes to the method. But the code I tried above gives me errors.
Please help me. Thank you.
Upvotes: 5
Views: 1701
Reputation: 147154
You've got Comparable
, so if we has a zero
, a[0]>0
could be replaced by a[0].compareTo(zero) > 0
(no, I think it's < 0
, I can never remember). But now we've run out of useful stuff from Double
and the like.
If Double
and friends weren't java.lang.Comparable
we could supply our own java.util.Comparator
. That is we take the implementation of comparison outside of the data object. We can also do that addition and multiplication.
public interface Testor<T> { // Choose a better name...
boolean isStriclyPositive(T value);
T add(T lhs, T rhs);
T square(T value);
}
static final Testor<Integer> INTEGER_TESTOR = new Testor<>() { // Java SE 7 diamond.
public boolean isStriclyPositive(Integer value) { return value > 0; }
public Integer add(Integer lhs, Integer rhs) { return lhs + rhs; }
public Integer square(Integer value) { return value*value; }
}
// ... same for Double, etc.; can't use an enum :( ...
test(new Integer[] { 42, 1972, 86 }, INTEGER_TESTOR);
public <T> void test(T[] a, Testor<T> testor) {
T b = a[0];
if (testor.isStrictlyPositive(a[0])) {
a[0] = testor.square(a[0]);
b = testor.add(b, a[1]);
}
}
Note for things like Short
, summing two of them will give you an int
.
(Usual Stack Overflow disclaimer: not so much as attempted to compile the code.)
Upvotes: 1
Reputation: 68847
You can't do this in Java with generics. That's a benefit of C++ for example.
In some way you can define this as "strange", because it is possible to use operators on Java's primitive wrappers. But that is because you can't use operators on java.lang.Number
, the superclass of the primitive wrappers.
Some resources:
Upvotes: 3
Reputation: 48196
all types (including the inferred generic types) except the primitives are Objects which don't support the arithmetic operations (the wrapper classes use boxing/unboxing to get the known psuedo behavior)
and type erasure makes the compiled code use casts to get the proper behavior (i.e. at runtime the JVM doesn't know what type was passed in which it would need to know to get the proper boxing/unboxing behavior)
the only (real) solution is to provide implementations for all primitives you want to support
Upvotes: 5