Java generic function for performing calculations on integer, on double?
Is this possible? Surely if you passed in a double, any 开发者_开发问答sort of function implementation code which casts an object to an Integer would not be able to work unless the cast 'Integer' was specifically used? I have a function like:
public static void increment(Object o){
Integer one = (Integer)o;
system.out.println(one++);
}
I cant see how this could be made generic for a double? I tried
public static <E> void increment(E obj){
E one = (E)obj;
system.out.println(one++);
}
but it didn't like it?
In Java, method arguments are passed by value. Therefore, incrementing a method argument will not change the caller's value. So, you must either return the new value:
double increment(double x) {
return x + 1;
}
or pass a reference type containing the value:
class MutableDouble {
double value;
}
void increment(MutableDouble d) {
d.value++;
}
In Java, type arguments must be of reference type, hence double is not a valid value for a type parameter. If you want primitive types, consider overloading the methods instead:
float increment(float f) {
return f + 1;
}
double increment(double d) {
return d + 1;
}
If you really want generics, you can do:
@SuppressWarnings("unchecked")
<N extends Number> N increment(N n) {
if (n instanceof Double) {
return (N) (Double) (((Double)n) + 1);
} else if (n instanceof Float) {
return (N) (Float) (((Float)n) + 1);
} else if ( ...
// handle remaining cases
} else if (n == null) {
throw new NullPointerException();
} else {
throw new IllegalArgumentException("Unexpected number type: " + n.getClass());
}
}
This is godawful ugly though. What are you trying to accomplish by defining such a method? There's probably is an easier way ...
You may want to read up on semantics that higher-level specialized languages have defined from cross-type arithmetic. A good example that I recommend is JSP EL specification.
It basically spells out how to implement such function...
http://www.google.com/url?sa=t&source=web&cd=7&ved=0CEwQFjAG&url=http%3A%2F%2Fflaka.googlecode.com%2Ffiles%2Fjsp-2_1-fr-spec-el.pdf&rct=j&q=jsp%20el%20specification&ei=erkwTZrZGJHogQfbxMWiCw&usg=AFQjCNH6oPO7WwgiHCBkST5vgsBxMZmWaQ&sig2=0hRqxe6G0brRGuzNOxEhGw&cad=rja
What if you downcast it to a Double?
public static void increment(Object o) {
Double d= (Double) o;
System.out.println(d + 1.0);
}
Update: I tried this and it worked:
public static void increment(Object o) {
Double d = Double.parseDouble(o.toString());
System.out.println(d + 1.0);
}
public static double increment(double d)
{
return d+1;
}
That will work for all primitive value types. Then all you have to do is cast the result ;-)
Assuming that you want to increment and get new value (not change immutable Integer instance), you can do something like this:
interface Arithmetics<T> {
T inc(T val);
}
class IntegerArithmetics implements Arithmetics<Integer> {
Integer inc(Integer val) { return val+1; }
}
//similarly DoubleArithmetics, BigIntegerArithmetics, ...
And call it to get your method:
public static <E> void increment(E obj, Arithmetics<E> arit){
System.out.println(arit.inc(obj));
}
Generic Java Math library does exactly that for you.
Only thing is that you need to pass Arithmetics
object around. If that is a big problem, you can initialize a Map<Class,Arithmetics>
, and use map.get(obj.getClass())
to get corresponding Arithmetics
.
精彩评论