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
- Ensure your converter's getTargetType() returns a non-null Class.
- Pass a non-null defaultValue so its class can be used as the target type.
- 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
- Implement getTargetType() on every custom AbstractConverter subclass.
- Route conversions through Convert / ConverterRegistry rather than calling raw converters with null defaults.
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
- PrimitiveConverter not allow null target type!
- Default value [{}]({}) is not the instance of [{}]
- Video URI is empty
- File not found!
- The object to build a hash code for must not be null
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/23c71acc08da92c3.
Report an issue: GitHub.