You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gson反序列化Java泛型抛出UnsupportedOperationException解决方法

问题原因

异常的核心原因是泛型参数传参与逻辑设计不匹配:
你调用addStompClient时传入的第一个参数是Category.class,这个对象本身的类型是Class<Category>,会让泛型T被推导为java.lang.Class,而非你预期的Category业务类。后续在onMessage方法中执行t.getClass()时,拿到的是java.lang.Class的类型对象,Gson尝试将业务JSON反序列化为Class类实例时,就会抛出你看到的类型适配器缺失异常。

修复步骤

直接调整参数定义和类型存储逻辑即可,不需要额外给Gson注册Class类型的适配器:

  • 修改addStompClient方法签名,将第一个参数的类型从泛型实例T改为字节码类型Class<T>
public <T> void addStompClient(Class<T> tClass, String url, String subscription, StompMessageListener<T> listener) {
    StompClient<T> sc = new StompClient<T>(tClass, URI.create(url));
    StompConnectionListener scl = new StompConnectionListener() {
        public void onConnecting() {}
        public void onConnected() {
            sc.subscribe(subscription, listener);
        }
        public void onDisconnected() {}
        
    };
    sc.setStompConnectionListener(scl);
    sc.connect();
    clients.add(sc);
}
  • 修改StompClient类的成员变量和构造方法,直接存储传入的字节码对象,不再存储泛型实例
@Getter
private Class<T> tClass;

protected StompClient(Class<T> tClass, URI serverUri) {
    super(serverUri);
    this.tClass = tClass;
}
  • 简化onMessage中的反序列化逻辑,直接使用存储的字节码对象做JSON转换,去掉冗余的getClass()调用和强转
case MESSAGE:
    Integer subscriptionId = Integer.valueOf(stompFrame.getHeaders().get(StompHeader.SUBSCRIPTION.toString()));
    // 直接用存储的tClass反序列化,不需要再取getClass()
    T test = new Gson().fromJson(stompFrame.getBody(), tClass);
    
    StompSubscription<T> listener = (StompSubscription<T>) subscriptions.get(subscriptionId);
    listener.getListener().onMessage(test);
    break;

修改完成后原有调用代码不需要调整,传入Category.class时,泛型会被正确推导为Category类型,反序列化得到的对象可以直接调用getName()等业务方法,不会再抛出异常。


内容的提问来源于stack exchange,提问作者Sean Rahman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:45:46