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

  1. For PhantomReference or custom Reference types, construct the instance manually: new PhantomReference<>(value, queue).
  2. If you only need WeakReference or SoftReference, ensure the target type is exactly those classes.
  3. Register a custom Converter for your Reference subtype in ConverterRegistry to handle it before the default ReferenceConverter.
  4. 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

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


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