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

Retrofit提交Raw JSON报错,伴生Place接口无法实例化异常求助

嘿,我来帮你搞定这个Retrofit的坑!

首先,咱们先揪出问题的根源:你遇到的java.lang.UnsupportedOperationException: Interface can't be instantiated! Interface name: com.google.android.gms.location.places.Place异常,本质是你的请求Model(或者CookDetails类)里用到了Place这个Google提供的接口作为字段。

Postman能正常跑是因为它直接发Raw JSON字符串,不需要处理Java对象的实例化;但Retrofit用Gson做序列化时,会尝试把你的Java对象转成JSON,而接口是不能被直接new出来的,Gson不知道怎么实例化这个Place接口,自然就报错了。

给你几个针对性的解决方案,按优先级排序:

1. 最省心:把接口换成自定义POJO类

既然你只需要把Place的相关数据传给后端,完全没必要用Google的Place接口,自己写一个包含所需字段的实体类就行:

// 自定义的Place实体类,只保留你需要传给后端的字段
public class MyPlace {
    private String placeId;
    private String name;
    private String address;
    // 其他你要传的字段,比如latitude、longitude

    // 别忘了加无参构造、getter/setter,或者用Lombok简化
}

然后把你原来Model类里的Place字段换成MyPlace:

public class YourRequestModel {
    private MyPlace place;
    // 其他原有字段...
}

这样Gson就能正常序列化这个实体类,不会再报错。

2. 自定义Gson TypeAdapter(如果必须用Place接口)

如果你因为某些原因一定要保留Place接口,可以给Gson写一个自定义的适配器,告诉它怎么序列化/反序列化Place对象:

public class PlaceTypeAdapter extends TypeAdapter<Place> {
    @Override
    public void write(JsonWriter out, Place value) throws IOException {
        // 把Place接口里的字段写入JSON,按后端需要的格式来
        out.beginObject();
        out.name("placeId").value(value.getId());
        out.name("name").value(value.getName());
        out.name("address").value(value.getAddress());
        // 按需添加其他字段
        out.endObject();
    }

    @Override
    public Place read(JsonReader in) throws IOException {
        // 如果你的接口需要接收后端返回的Place数据,这里要实现反序列化逻辑
        // 用Google提供的Place.Builder来创建实例
        in.beginObject();
        String placeId = null;
        CharSequence name = null;
        CharSequence address = null;

        while (in.hasNext()) {
            switch (in.nextName()) {
                case "placeId":
                    placeId = in.nextString();
                    break;
                case "name":
                    name = in.nextString();
                    break;
                case "address":
                    address = in.nextString();
                    break;
            }
        }
        in.endObject();

        return new Place.Builder()
                .setId(placeId)
                .setName(name)
                .setAddress(address)
                .build();
    }
}

然后在Retrofit的Gson配置里注册这个适配器:

Gson customGson = new GsonBuilder()
        .registerTypeAdapter(Place.class, new PlaceTypeAdapter())
        .create();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(YOUR_BASE_URL)
        .addConverterFactory(GsonConverterFactory.create(customGson))
        .build();

3. 检查CookDetails类

别忘了排查你的CookDetails类,确保里面也没有用类似的接口类型作为字段,所有参与序列化的字段都必须是可实例化的类(不是接口、抽象类)。

按上面的方法调整后,Retrofit应该就能正常发送请求啦!

内容的提问来源于stack exchange,提问作者Gulfam Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:18:37