2010-09-19 42 views
2

我正在寻找一种简单,简洁的方式将给定的Number对象转换为给定数字类型的对象。在Java中的数字对象之间的转换

  • 由于收缩转换损失的精度是好的
  • 我不想去通过字符串。

我需要这样的东西:

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

有没有办法做到这一点不检查的所有类型的组合?

+1

无论实现如何,我至少会将方法签名重写为'public static N convert(Number number,Class type)''。这将返回完全指定的数字类型,这在后期处理中可能具有优势。 – BalusC 2010-09-19 18:04:29

+0

@BalusC:你说得对。谢谢! – 2010-09-19 19:21:53

回答

4

我觉得最明显的方法是使用蛮力:

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; 
} 

你可以使用反射,但我发现更多的hackish。

+0

+1以避免反思。反思会减慢应用程序的速度......我会这样做。 – 2010-09-19 18:09:14

+0

不错。我将使用这个解决方案。通过这些类型的静态方法,不需要实际检查所有类型的组合。谢谢! – 2010-09-19 19:26:11

+0

这很好用。我建议处理num == null。 – Bampfer 2015-01-08 17:46:44

1

也许转换通过BigDecimal会工作?

+0

我怀疑这需要转换为字符串或使用反射,对不对? – 2010-09-19 16:28:27

4

您可以使用类似:

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

这依赖于一个事实,即Number有一个像longValue()floatValue()方法等

至于BigIntegerAtomicInteger - 你可以沉思使用其构造函数,它接受一个参数 - 原始类型。

+0

+1。需要检查'AtomicInteger','AtomicLong','BigDecimal','BigInteger'类型没有作为targetType传入,因为它们在Number中没有xxxValue()方法。 – 2010-09-19 16:17:40

+0

@Noel M:我不需要处理这些类型。但是,现在我意识到性能很重要。我可能会考虑详细的解决方案,而不是......无论如何,我喜欢这个解决方案的创造力:) – 2010-09-19 16:23:00