in freemarker-core/src/main/java/freemarker/ext/beans/BeansWrapper.java [1542:1595]
static Number forceUnwrappedNumberToType(final Number n, final Class<?> targetType, final boolean bugfixed) {
// We try to order the conditions by decreasing probability.
if (targetType == n.getClass()) {
return n;
} else if (targetType == int.class || targetType == Integer.class) {
return n instanceof Integer ? (Integer) n : Integer.valueOf(n.intValue());
} else if (targetType == long.class || targetType == Long.class) {
return n instanceof Long ? (Long) n : Long.valueOf(n.longValue());
} else if (targetType == double.class || targetType == Double.class) {
return n instanceof Double ? (Double) n : Double.valueOf(n.doubleValue());
} else if (targetType == BigDecimal.class) {
if (n instanceof BigDecimal) {
return n;
} else if (n instanceof BigInteger) {
return new BigDecimal((BigInteger) n);
} else if (n instanceof Long) {
// Because we can't represent long accurately as double
return BigDecimal.valueOf(n.longValue());
} else {
return new BigDecimal(n.doubleValue());
}
} else if (targetType == float.class || targetType == Float.class) {
return n instanceof Float ? (Float) n : Float.valueOf(n.floatValue());
} else if (targetType == byte.class || targetType == Byte.class) {
return n instanceof Byte ? (Byte) n : Byte.valueOf(n.byteValue());
} else if (targetType == short.class || targetType == Short.class) {
return n instanceof Short ? (Short) n : Short.valueOf(n.shortValue());
} else if (targetType == BigInteger.class) {
if (n instanceof BigInteger) {
return n;
} else if (bugfixed) {
if (n instanceof OverloadedNumberUtil.IntegerBigDecimal) {
return ((OverloadedNumberUtil.IntegerBigDecimal) n).bigIntegerValue();
} else if (n instanceof BigDecimal) {
return ((BigDecimal) n).toBigInteger();
} else {
return BigInteger.valueOf(n.longValue());
}
} else {
// This is wrong, because something like "123.4" will cause NumberFormatException instead of flooring.
return new BigInteger(n.toString());
}
} else {
final Number oriN = n instanceof OverloadedNumberUtil.NumberWithFallbackType
? ((OverloadedNumberUtil.NumberWithFallbackType) n).getSourceNumber() : n;
if (targetType.isInstance(oriN)) {
// Handle nonstandard Number subclasses as well as directly java.lang.Number.
return oriN;
} else {
// Fails
return null;
}
}
}