chinabugotech/hutool · error · UnsupportedOperationException
Unsupport Reference type: {}
Error message
Unsupport Reference type: {} What it means
Thrown by ReferenceConverter.convertInternal() when the target Reference subclass is neither WeakReference nor SoftReference. The converter explicitly only instantiates those two; any other Reference subtype (e.g., PhantomReference or a custom Reference subclass) falls through to UnsupportedOperationException.
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/convert/impl/ReferenceConverter.java:53
protected Reference<?> convertInternal(Object value) {
//尝试将值转换为Reference泛型的类型
Object targetValue = null;
final Type paramType = TypeUtil.getTypeArgument(targetType);
if(false == TypeUtil.isUnknown(paramType)){
targetValue = ConverterRegistry.getInstance().convert(paramType, value);
}
if(null == targetValue){
targetValue = value;
}
if(this.targetType == WeakReference.class){
return new WeakReference(targetValue);
}else if(this.targetType == SoftReference.class){
return new SoftReference(targetValue);
}
throw new UnsupportedOperationException(StrUtil.format("Unsupport Reference type: {}", this.targetType.getName()));
}
}
View on GitHub (pinned to 8870454b2a)
Solutions
- For PhantomReference or custom Reference types, construct the instance manually: new PhantomReference<>(value, queue).
- If you only need WeakReference or SoftReference, ensure the target type is exactly those classes.
- Register a custom Converter for your Reference subtype in ConverterRegistry to handle it before the default ReferenceConverter.
- Avoid routing arbitrary Reference subtypes through Convert.convert(); construct them directly.
Example fix
// before Convert.convert(PhantomReference.class, myObject); // throws // after ReferenceQueue<Object> queue = new ReferenceQueue<>(); PhantomReference<Object> ref = new PhantomReference<>(myObject, queue);
Defensive patterns
Strategy: type-guard
Validate before calling
if (targetType != WeakReference.class && targetType != SoftReference.class) {
// construct manually instead of using the converter
throw new UnsupportedOperationException("Use manual construction for " + targetType);
}
Convert.convert(targetType, value); Type guard
static boolean isSupportedReferenceType(Class<? extends Reference> type) {
return type == WeakReference.class || type == SoftReference.class;
} Try / catch
try {
return Convert.convert(targetType, value);
} catch (UnsupportedOperationException e) {
// manually construct unsupported Reference type
return targetType.getConstructor(Object.class).newInstance(value);
} Prevention
- Only route WeakReference and SoftReference through Convert.convert().
- Construct PhantomReference or custom Reference types directly with new.
- Register a custom converter for non-standard Reference subtypes.
When it happens
Trigger: Calling Convert.convert(PhantomReference.class, value). Registering a custom Reference subclass type and routing it through the default ReferenceConverter. Passing a user-defined class extending Reference<T> as the conversion target.
Common situations: Using PhantomReference in cache or resource-tracking code and attempting Hutool conversion. Custom Reference subclasses for specialized cleanup logic. Generic framework code that converts into any Reference subtype selected at runtime.
Related errors
- Cache values Iterator is not support to modify.
- proxied annotation can not reset attributes
- remove() method not supported for a NodeListIterator.
- [type] and [defaultValue] are both null for Converter [{}],
- Default value [{}]({}) is not the instance of [{}]
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/3f4b50f24f857e24.
Report an issue: GitHub.