chinabugotech/hutool · error · NullPointerException

[type] and [defaultValue] are both null for Converter [{}],

Error message

[type] and [defaultValue] are both null for Converter [{}], we can not know what type to convert !

What it means

AbstractConverter.convert(Object, T) resolves the target type from getTargetType(); if that returns null it falls back to defaultValue.getClass(). When BOTH are null it cannot decide the target type and throws NullPointerException.

Source

Thrown at hutool-core/src/main/java/cn/hutool/core/convert/AbstractConverter.java:43

	 * @param value        被转换的值
	 * @param defaultValue 默认值
	 * @return 转换后的值
	 * @since 4.5.7
	 */
	public T convertQuietly(Object value, T defaultValue) {
		try {
			return convert(value, defaultValue);
		} catch (Exception e) {
			return defaultValue;
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public T convert(Object value, T defaultValue) {
		Class<T> targetType = getTargetType();
		if (null == targetType && null == defaultValue) {
			throw new NullPointerException(StrUtil.format("[type] and [defaultValue] are both null for Converter [{}], we can not know what type to convert !", this.getClass().getName()));
		}
		if (null == targetType) {
			// 目标类型不确定时使用默认值的类型
			targetType = (Class<T>) defaultValue.getClass();
		}
		if (null == value) {
			return defaultValue;
		}

		if (null == defaultValue || targetType.isInstance(defaultValue)) {
			if (targetType.isInstance(value) && false == Map.class.isAssignableFrom(targetType)) {
				// 除Map外,已经是目标类型,不需要转换(Map类型涉及参数类型,需要单独转换)
				return targetType.cast(value);
			}
			final T result = convertInternal(value);
			return ((null == result) ? defaultValue : result);
		} else {
			throw new IllegalArgumentException(

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Ensure your converter's getTargetType() returns a non-null Class.
  2. Pass a non-null defaultValue so its class can be used as the target type.
  3. Avoid calling convert(value, null) directly; go through Convert / ConverterRegistry which always binds a target type.

Example fix

// before
converter.convert(value, null); // getTargetType() returns null

// after - pass a typed default
Integer result = converter.convert(value, Integer.valueOf(0));
Defensive patterns

Strategy: validation

Validate before calling

if (converter.getTargetType() == null && defaultValue == null) {
    throw new IllegalStateException("Converter has no target type and no default: " + converter);
}
converter.convert(value, defaultValue);

Try / catch

try {
    converter.convert(value, null);
} catch (NullPointerException e) {
    if (e.getMessage().contains("both null")) { /* supply default or skip */ }
    else throw e;
}

Prevention

When it happens

Trigger: Calling converter.convert(value, null) on a converter whose getTargetType() returns null (e.g. a custom AbstractConverter subclass that never set its targetType field, or a misused CastConverter).

Common situations: Custom Converter implementations that override getTargetType() to return null; generic utility code that passes null defaults through.

Related errors


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