¿Por qué no se verifica el desbordamiento de rango al convertir de “Number” a “Float” o “Double” en el código fuente del framework Spring Boot?
Por favor, revise el fragmento de código fuente que se encuentra en org.springframework.util.NumberUtils#convertNumberToTargetClass(), la firma del método es +
public static
throws IllegalArgumentException {
… …
… …
else if (Float.class == targetClass) {
return (T) Float.valueOf(number.floatValue());
}
…. ….
…. ….
}
Cuando se convierte “number” a “Float”, no se verifica si “number” sobrepasa el rango de “Float” o no. Pero sí se verifica al convertir “number” a “Byte”, “Integer” o “Short”, como se muestra a continuación:
public static
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();
}
// Efectivamente análogo a BigInteger.longValueExact() en JDK 8
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(“No se pudo convertir el número [” + number + “] del tipo [” +
number.getClass().getName() + “] a la clase objetivo [” + targetClass.getName() + “]: desbordamiento”);
}
¡Tengo mucha curiosidad por saber por qué!
davy.ai
La razón por la que el método
convertNumberToTargetClass
no verifica si hay desbordamiento al convertir aFloat
es porqueFloat
es un número de punto flotante IEEE 754 de precisión simple de 32 bits, cuyo rango ya está limitado. Puede representar valores que van desde aproximadamente 1,4 × 10⁻⁴⁵ hasta 3,4 × 10³⁸. Por lo tanto, es muy poco probable que ocurra un desbordamiento al convertir aFloat
desde cualquier otro tipo numérico.Por otro lado, al convertir a
Byte
,Integer
oShort
, que tienen un rango más estrecho queFloat
, hay una mayor probabilidad de que ocurra un desbordamiento. Por lo tanto, el métodoconvertNumberToTargetClass
realiza verificaciones de desbordamiento para estos tipos para asegurarse de que el valor convertido pueda caber dentro del rango del tipo objetivo.En resumen, el método
convertNumberToTargetClass
no verifica si hay desbordamiento al convertir aFloat
porque el rango deFloat
ya está limitado, mientras que realiza verificaciones de desbordamiento para tipos más estrechos para evitar posibles desbordamientos.