chinabugotech/hutool · error · UnsupportedOperationException

Unsupport Number type: {}

Error message

Unsupport Number type: {}

What it means

NumberConverter handles Byte, Short, Integer, AtomicInteger, Long, AtomicLong, Float, Double, DoubleAdder, LongAdder, BigDecimal, BigInteger, and the generic Number supertype. Any other Number subclass (or class passed in) as targetType throws UnsupportedOperationException.

Source

Thrown at hutool-core/src/main/java/cn/hutool/core/convert/impl/NumberConverter.java:220

				final DoubleAdder doubleAdder = new DoubleAdder();
				doubleAdder.add(number.doubleValue());
				return doubleAdder;
			}
		} else if (BigDecimal.class == targetType) {
			return toBigDecimal(value, toStrFunc);
		} else if (BigInteger.class == targetType) {
			return toBigInteger(value, toStrFunc);
		} else if (Number.class == targetType) {
			if (value instanceof Number) {
				return (Number) value;
			} else if (value instanceof Boolean) {
				return BooleanUtil.toInteger((Boolean) value);
			}
			final String valueStr = toStrFunc.apply((value));
			return StrUtil.isBlank(valueStr) ? null : NumberUtil.parseNumber(valueStr);
		}

		throw new UnsupportedOperationException(StrUtil.format("Unsupport Number type: {}", targetType.getName()));
	}

	/**
	 * 转换为BigDecimal<br>
	 * 如果给定的值为空,或者转换失败,返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value     被转换的值
	 * @param toStrFunc 转换为字符串的函数规则
	 * @return 结果
	 */
	private static BigDecimal toBigDecimal(Object value, Function<Object, String> toStrFunc) {
		if (value instanceof Number) {
			return NumberUtil.toBigDecimal((Number) value);
		} else if (value instanceof Boolean) {
			return ((boolean) value) ? BigDecimal.ONE : BigDecimal.ZERO;
		}

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Target a supported boxed type (Long/Double/BigDecimal) then adapt to your type.
  2. Register a custom Converter for your Number subtype via ConverterRegistry.putCustom.
  3. If you only need a generic number, target Number.class which uses NumberUtil.parseNumber.

Example fix

// before
MyNum n = Convert.convert("42", MyNum.class); // MyNum extends Number

// after - supported type then adapt
BigDecimal bd = Convert.convert("42", BigDecimal.class);
MyNum n = new MyNum(bd);
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<Class<?>> SUPPORTED = Set.of(
        Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class,
        BigDecimal.class, BigInteger.class, Number.class,
        AtomicInteger.class, AtomicLong.class, DoubleAdder.class, LongAdder.class);
if (!SUPPORTED.contains(targetType)) {
    targetType = BigDecimal.class; // safe generic fallback
}
new NumberConverter(targetType);

Try / catch

try {
    return new NumberConverter(targetType).convert(value, null);
} catch (UnsupportedOperationException e) {
    if (e.getMessage().startsWith("Unsupport Number type")) {
        return new NumberConverter(BigDecimal.class).convert(value, null);
    }
    throw e;
}

Prevention

When it happens

Trigger: Constructing new NumberConverter(customNumberSubclass.class) where the subclass is not in the supported set; converting to a third-party Number type.

Common situations: Custom Number subclasses, third-party numeric wrappers, or accidentally passing a non-Number class.

Related errors


AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14). Data as JSON: /api/errors/97d28a69f9a31b63. Report an issue: GitHub.