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

开发实时货币转换APP遭遇java.lang.NullPointerException求助

修复货币转换APP的NullPointerException问题

问题根源

崩溃的直接原因是response.body()返回了null,导致你调用res.getAsJsonObject("rates")时触发空指针异常。这种情况通常发生在API请求未返回2xx成功响应(比如400参数错误、401未授权、500服务器错误),此时Retrofit不会返回响应体,response.body()自然为null。

修复步骤

你需要在代码中添加多层空值校验,同时处理各类异常场景:

  1. 先校验请求是否成功:通过response.isSuccessful()判断HTTP响应是否正常
  2. 校验响应体是否存在:确保res不为null后再操作
  3. 校验"rates"字段是否有效:避免API返回结构不符合预期导致的空指针
  4. 处理用户输入的异常情况:防止空值或非数字输入触发格式转换异常

修改后的代码如下:

MoneyButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        RetrofitInterface retrofitInterface = RetrofitBuilder.getRetrofitInstance().create(RetrofitInterface.class);
        Call<JsonObject> call = retrofitInterface.getExchangeCurrency(MoneyTo.getSelectedItem().toString());
        call.enqueue(new Callback<JsonObject>() {
            @Override
            public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                // 1. 判断请求是否成功
                if (!response.isSuccessful()) {
                    MoneyTextView.setText("请求失败:" + response.code());
                    return;
                }
                
                JsonObject res = response.body();
                // 2. 校验响应体是否为空
                if (res == null) {
                    MoneyTextView.setText("未获取到数据");
                    return;
                }
                
                // 3. 校验"rates"字段是否存在且为JsonObject类型
                if (!res.has("rates") || !res.get("rates").isJsonObject()) {
                    MoneyTextView.setText("数据格式错误");
                    return;
                }
                JsonObject rates = res.getAsJsonObject("rates");
                
                // 4. 处理用户输入的金额
                String inputStr = MoneyEd.getText().toString().trim();
                if (inputStr.isEmpty()) {
                    MoneyTextView.setText("请输入金额");
                    return;
                }
                double currency;
                try {
                    currency = Double.parseDouble(inputStr);
                } catch (NumberFormatException e) {
                    MoneyTextView.setText("请输入有效的数字");
                    return;
                }
                
                // 5. 校验目标货币汇率是否存在
                String targetCurrency = MoneyFrom.getSelectedItem().toString();
                if (!rates.has(targetCurrency) || !rates.get(targetCurrency).isJsonPrimitive()) {
                    MoneyTextView.setText("不支持该货币转换");
                    return;
                }
                double multiplier = rates.get(targetCurrency).getAsDouble();
                
                double result = currency * multiplier;
                MoneyTextView.setText(String.format("%.2f", result)); // 格式化保留两位小数更友好
            }

            @Override
            public void onFailure(Call<JsonObject> call, Throwable t) {
                // 不要空实现,处理网络失败场景
                MoneyTextView.setText("网络连接失败");
                t.printStackTrace(); // 调试时打印异常,发布版可移除
            }
        });
    }
});

额外建议

  • 调试时可以打印response.code()和response.errorBody().string(),查看API返回的具体错误信息(比如参数是否正确、API密钥是否有效)
  • 给Spinner设置默认选中项,避免MoneyTo.getSelectedItem()返回null
  • 优先使用Double.parseDouble()配合try-catch,比直接用Double.valueOf()更安全

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:30:43