使用JSONObject转换为字符串时枚举值为空,如何解决该问题?
解决JSONObject中添加枚举值显示为空的问题
问题重现
尝试往JSONObject中添加枚举值后,打印输出或转换为字符串时,枚举值显示为空对象{}。
代码示例
package com.test; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; public class TestJson { public static void main(String[] args) { JSONObject json_obj = new JSONObject(); json_obj.put("name", "paul"); Map<String, enumObj> a = new HashMap<>(); a.put("val", enumObj.LOW); json_obj.put("json_obj", a); System.out.println(json_obj); } public enum enumObj{ LOW, MEDIUM, HIGH } }
输出结果
{"name":"paul","json_obj":{"val":{}}}
原因分析
org.json库的JSONObject默认无法正确序列化Java枚举类型。它会把枚举当作普通Java对象处理,但枚举的内部字段均为非公开状态,因此序列化后只会输出空对象{}。
解决方案
方案1:存储枚举的名称(推荐)
使用枚举的name()方法获取其字符串形式,序列化后会直接显示枚举的字面量:
Map<String, String> a = new HashMap<>(); a.put("val", enumObj.LOW.name()); // 存入枚举的名称字符串
修改后的完整代码:
package com.test; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; public class TestJson { public static void main(String[] args) { JSONObject json_obj = new JSONObject(); json_obj.put("name", "paul"); Map<String, String> a = new HashMap<>(); a.put("val", enumObj.LOW.name()); json_obj.put("json_obj", a); System.out.println(json_obj); } public enum enumObj{ LOW, MEDIUM, HIGH } }
修改后的输出:
{"name":"paul","json_obj":{"val":"LOW"}}
方案2:存储枚举的序数(不推荐)
如果需要用数字表示枚举,可使用ordinal()方法,但该方法返回的是枚举在声明中的顺序索引(从0开始),一旦枚举的声明顺序改变,对应的值也会变化,因此不推荐使用:
Map<String, Integer> a = new HashMap<>(); a.put("val", enumObj.LOW.ordinal());
方案3:自定义枚举的toString方法
给枚举重写toString()方法,存入时直接使用枚举对象,org.json会自动调用其toString()方法输出:
public enum enumObj{ LOW, MEDIUM, HIGH; @Override public String toString() { return this.name(); // 也可以自定义返回内容 } }
修改后无需调整Map类型,直接存入枚举对象即可得到正确的字符串输出。
内容的提问来源于stack exchange,提问作者user2478236
相关产品推荐
相关产品推荐

