views:

71

answers:

3

I am looking for a simple, concise way to convert a given Number object to an object of a given numeric type.

  • Loss of precision due to narrowing conversions is fine
  • I prefer not to go through strings.

I need something like:

private static Number convert(Number num, Class<? extends Number> targetType)

Is there a way to do it without checking all the combinations of types?

+1  A: 

Perhaps converting via BigDecimal would work?

Noel M
I suspect this requires either converting to String or using reflection, right?
Eyal Schneider
+4  A: 

You can use something like:

String simpleName = targetType.getSimpleName().toLowerCase();
if (simpleName.equals("integer")) {
   simpleName = "int";
}
Method m = number.getClass().getMethod(simpleName + "Value");
return (Number) m.invoke(number);

This relies on the fact that Number has methods like longValue(), floatValue(), etc.

As for BigInteger or AtomicInteger - you can use their constructor reflectively, which accepts one argument - the primitive type.

Bozho
+1. Would need to check that the types `AtomicInteger`, `AtomicLong`, `BigDecimal`, `BigInteger`, aren't passed in as targetType as they don't have a xxxValue() method on `Number`.
Noel M
@Noel M: I don't need to handle these types. However, now I realize that performance IS important. I may consider the verbose solution instead... Anyway, I like the creativity of this solution :)
Eyal Schneider
+4  A: 

I think the clearest way is to use brute force:

private static Number convert(Number num, Class<? extends Number> targetType) {
    Number result = null;
    if (Byte.class.equals(targetType)) {
        result = Byte.valueOf(num.byteValue());
    } else if (Short.class.equals(targetType)) {
        result = Short.valueOf(num.shortValue());
    } else if (...) {
         ...
    } else {
        throw new IllegalArgumentException("targetType is not a Number");
    }
    return result;
}

You might use reflection, but I find that more hackish.

gpeche
+1 to avoid reflection. Reflection will slow down the application... I would do it exactly the same.
Martijn Courteaux
Nice. I will use this solution. With the static methods of these types there is no need to actually check all type combinations. Thanks!
Eyal Schneider