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

Android Java JSON解析问题:属性缺失致空指针,求优雅解决方案

嘿,这个问题我太懂了——一堆重复的isNull判断确实会把代码搞得又长又乱,尤其是要处理12个参数的时候!给你分享几个我平时常用的优雅方案,帮你把代码瘦下来:

方案1:封装通用工具类(Java/Kotlin通用)

把判断字段是否存在、提取值的逻辑抽成工具类的静态方法,这样每次调用只需要一行代码,避免重复造轮子。

比如写一个JsonUtils类:

public class JsonUtils {
    // 获取字符串,字段缺失返回null
    public static String getStringOpt(JSONObject obj, String key) {
        return obj.isNull(key) ? null : obj.optString(key);
    }

    // 重载:获取字符串,字段缺失返回指定默认值
    public static String getStringOpt(JSONObject obj, String key, String defaultValue) {
        return obj.isNull(key) ? defaultValue : obj.optString(key, defaultValue);
    }

    // 同理封装其他类型,比如int
    public static int getIntOpt(JSONObject obj, String key, int defaultValue) {
        return obj.isNull(key) ? defaultValue : obj.optInt(key, defaultValue);
    }

    // 按需添加getLongOpt、getBooleanOpt等方法
}

调用的时候就非常简洁:

JSONObject object = jsonArray.getJSONObject(i);
String name = JsonUtils.getStringOpt(object, "name");
int age = JsonUtils.getIntOpt(object, "age", 0);
String email = JsonUtils.getStringOpt(object, "email", "unknown@example.com");
// 剩下的10个参数都是类似一行搞定

方案2:用Gson映射为实体类(推荐结构化解析)

如果你的项目已经在用Gson(Android开发几乎标配),直接把JSON映射成实体类是最省心的方式——Gson会自动处理缺失的字段,要么赋值为null(引用类型),要么用你设置的默认值(基本类型),完全不用手动判断。

Kotlin版本:

// 定义数据类,给每个字段设置默认值
data class User(
    @SerializedName("name") val name: String? = null,
    @SerializedName("age") val age: Int = 0,
    @SerializedName("email") val email: String? = null,
    // ... 剩下的9个字段都按这个格式设置
)

解析时直接转成实体类:

val user = Gson().fromJson(jsonArray.getJSONObject(i).toString(), User::class.java)
// 直接用user.name、user.age即可,缺失的字段会用默认值填充

Java版本:

public class User {
    @Nullable // 标记字段可为null
    private String name;
    private int age = 0; // 给基本类型设置默认值
    @Nullable
    private String email;
    // ... 剩下的字段

    // 必须要有无参构造器(Gson解析需要)
    public User() {}

    // 生成getter/setter方法
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    // ... 其他getter/setter
}

解析代码:

User user = new Gson().fromJson(jsonArray.getJSONObject(i).toString(), User.class);
// 直接调用user.getName(),字段缺失时返回null,不会抛空指针

方案3:Kotlin专属:扩展函数让调用更丝滑

如果是Kotlin项目,给JSONObject写几个扩展函数,调用起来就像原生方法一样自然:

// 扩展函数:获取字符串,缺失返回null
fun JSONObject.getStringOrNull(key: String): String? {
    return if (isNull(key)) null else optString(key)
}

// 扩展函数:获取int,缺失返回默认值(默认0)
fun JSONObject.getIntOrDefault(key: String, defaultValue: Int = 0): Int {
    return if (isNull(key)) defaultValue else optInt(key, defaultValue)
}

// 按需添加其他类型的扩展函数,比如getLongOrDefault、getBooleanOrNull等

调用的时候直接用:

val jsonObject = jsonArray.getJSONObject(i)
val name = jsonObject.getStringOrNull("name")
val age = jsonObject.getIntOrDefault("age")
val email = jsonObject.getStringOrNull("email")
// 剩下的参数同样一行搞定

小提示

  • 如果项目还没引入Gson,方案1的工具类是零成本的选择;
  • 方案2的实体类方式更适合长期维护,代码更清晰、面向对象;
  • Kotlin项目优先选方案3,语法简洁到飞起~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:24:59