Issue
please look at the source code snippet that is from org.springframework.util.NumberUtils#convertNumberToTargetClass()
, the method signature is + <T extends Number> T convertNumberToTargetClass(number:Number, targetClass:Class<?>)
public static <T extends Number> T convertNumberToTargetClass(Number number, Class<T> targetClass)
throws IllegalArgumentException {
... ...
... ...
else if (Float.class == targetClass) {
return (T) Float.valueOf(number.floatValue());
}
.... ....
.... ....
}
When converting number
to Float
, it doesn't check whether the number
overflows the range of Float
or not. But it does check that when converting number to Byte
, Integer
or Short
, as showing below:
public static <T extends Number> T convertNumberToTargetClass(Number number, Class<T> targetClass)
throws IllegalArgumentException {
... ...
... ...
else if (Byte.class == targetClass) {
long value = checkedLongValue(number, targetClass);
if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
raiseOverflowException(number, targetClass);
}
return (T) Byte.valueOf(number.byteValue());
}
... ...
... ...
}
private static long checkedLongValue(Number number, Class<? extends Number> targetClass) {
BigInteger bigInt = null;
if (number instanceof BigInteger) {
bigInt = (BigInteger) number;
}
else if (number instanceof BigDecimal) {
bigInt = ((BigDecimal) number).toBigInteger();
}
// Effectively analogous to JDK 8's BigInteger.longValueExact()
if (bigInt != null && (bigInt.compareTo(LONG_MIN) < 0 || bigInt.compareTo(LONG_MAX) > 0)) {
raiseOverflowException(number, targetClass);
}
return number.longValue();
}
private static void raiseOverflowException(Number number, Class<?> targetClass) {
throw new IllegalArgumentException("Could not convert number [" + number + "] of type [" +
number.getClass().getName() + "] to target class [" + targetClass.getName() + "]: overflow");
}
I'm really curious why!
Solution
Because there is no overflow.
If you do something like this:
Float aFloat = NumberUtils.convertNumberToTargetClass(Double.MAX_VALUE, Float.class);
The value of aFloat will be Infinity.
Checkout the API doc: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Float.html
Answered By - Simon Martinelli