能否实现通用的JSON getPath()函数?Java技术问询
方案可行性分析与代码优化建议
你的核心思路——让函数返回Object基类,由调用者自行转换类型——是完全可行的,符合你当前的学习阶段需求,也能满足目标调用场景。不过现有代码存在几个明显问题,得先修正才能正常工作:
现有代码的问题
- 初始化错误:
retOb = new Object()毫无意义,应该直接把初始值设为传入的json对象,不然第一次循环无法正确获取路径节点。 - 循环逻辑错误:当前循环只会取路径数组的最后一个有效节点,没有逐层遍历。比如传入
{"batter", "0", "type"},代码只会检查json里有没有"type"键,完全没处理前面的"batter"和"0"。 - 类型判断缺失:路径里的数组索引(比如
0)是数字,但你用String接收后,没有判断当前节点是JSONArray还是JSONObject,没法正确访问数组元素。 - 语法错误:
System.out.println那行有括号不匹配,而且强制转JSONObject会在retOb是数组或字符串时报错。
修正后的核心逻辑示例
先实现数组路径的版本,再扩展字符串路径(用.分割):
1. 数组路径版本
public Object getPath(Object currentNode, String[] path) { for (String segment : path) { if (currentNode instanceof JSONObject jsonObj) { // 当前节点是JSON对象,按键取值 if (jsonObj.has(segment)) { currentNode = jsonObj.get(segment); } else { // 可选:路径不存在时返回null或抛出异常 return null; } } else if (currentNode instanceof JSONArray jsonArr) { // 当前节点是JSON数组,把segment转成索引 try { int index = Integer.parseInt(segment); if (index >= 0 && index < jsonArr.length()) { currentNode = jsonArr.get(index); } else { return null; } } catch (NumberFormatException e) { // 数组节点遇到非数字路径,返回null return null; } } else { // 当前节点是基本类型(字符串/数字等),无法继续遍历 return null; } } return currentNode; }
2. 字符串路径版本(基于上面的方法)
public Object getPath(JSONObject json, String pathStr) { // 用.分割路径字符串,注意如果键里包含.需要特殊处理,这里先按简单场景实现 String[] pathSegments = pathStr.split("\\."); return getPath(json, pathSegments); }
调用示例
// 示例JSON String jsonStr = "{\"type\":\"donut\",\"batter\":[{\"id\":\"1001\",\"type\":\"Regular\"},{\"id\":\"1002\",\"type\":\"Chocolate\"}]}"; JSONObject theJson = new JSONObject(jsonStr); // 调用数组路径 JSONArray batterArr = (JSONArray) getPath(theJson, new String[]{"batter"}); String regularType = (String) getPath(theJson, new String[]{"batter", "0", "type"}); // 调用字符串路径 String sameRegularType = (String) getPath(theJson, "batter.0.type");
补充说明
- 你当前的想法(返回
Object让调用者转换)在学习阶段很合理,既简化了函数逻辑,也能让你熟悉Java的类型转换。 - 后续可以添加异常处理(比如路径不存在、类型不匹配时抛出自定义异常),或者给调用者提供类型安全的重载方法(比如
getStringPath、getJSONArrayPath),但这都是进阶内容。 - 注意如果JSON里的键包含
.字符,split("\\.")会出错,这种场景可以考虑用其他分隔符,或者在路径里转义.,不过这属于复杂场景,现阶段可以先忽略。
内容的提问来源于stack exchange,提问作者Keith
相关产品推荐
相关产品推荐

