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

Java使用栈验证JSON字符串有效性的代码问题排查

JSON验证代码问题排查

问题概述

我用Stack实现了一个JSON有效性验证的Java代码,但测试用例assertTrue(JsonValidator.isValidJSON("\"{\""), "The brackets and quotes are balanced, making this a valid JSON string")始终返回false,我认为该用例是有效的JSON字符串,需要排查问题。

原代码

public class JsonValidator {

public static boolean isValidJSON(String jsonString) {
    Stack<Character> stack = new Stack<>();
    for (char c : jsonString.toCharArray()) {
        switch (c) {
        case '{':
            stack.push(c);
            break;
        case '}':
            if (stack.isEmpty()) {
                return false;
            }
            Character last1 = stack.pop();
            if (last1 != '{') {
                return false;
            }
            break;
        case '[':
            stack.push(c);
            break;
        case ']':
            if (stack.isEmpty()) {
                return false;
            }
            Character last2 = stack.pop();
            if (last2 != '[') {
                return false;
            }
            break;

        case '"':
            if (stack.isEmpty()) {
                return false;
            }
            Character last3 = stack.peek();
            if (last3 == '"') {
                stack.pop();
            } else {
                stack.push(c);
            }

            stack.push(c);
        }

    }
    return stack.isEmpty();
}
}

问题分析

1. 引号分支重复入栈

在case '"'的逻辑末尾,多写了一行stack.push(c);,这会导致无论前面是弹出匹配的引号还是压入新引号,最终都会再压入一次引号。比如处理第一个引号时,先压入一次,末尾再压入一次,栈里会有两个引号;处理第二个引号时,弹出一个,末尾又压入一个,栈里始终剩一个引号,最终栈无法为空,返回false。

2. 错误拒绝引号开头的JSON

代码中处理引号时,首先判断if (stack.isEmpty()) { return false; },但根据JSON规范,单独的字符串值(比如"abc")是有效的JSON,此时栈初始为空,处理第一个引号时直接返回false,逻辑错误。

3. 测试用例的有效性

你传入的测试用例"\"{\""实际对应字符串是"{(双引号包裹左大括号),这是一个合法的JSON字符串值,本身是有效的,但原代码的逻辑错误导致返回false。

修复后的代码

import java.util.Stack;

public class JsonValidator {

    public static boolean isValidJSON(String jsonString) {
        Stack<Character> stack = new Stack<>();
        for (char c : jsonString.toCharArray()) {
            switch (c) {
                case '{':
                case '[':
                    stack.push(c);
                    break;
                case '}':
                    if (stack.isEmpty() || stack.pop() != '{') {
                        return false;
                    }
                    break;
                case ']':
                    if (stack.isEmpty() || stack.pop() != '[') {
                        return false;
                    }
                    break;
                case '"':
                    // 匹配引号:栈顶是引号则弹出,否则压入
                    if (!stack.isEmpty() && stack.peek() == '"') {
                        stack.pop();
                    } else {
                        stack.push(c);
                    }
                    break;
                // 其他JSON允许的字符(冒号、逗号、数字、字母等)暂不处理,不影响括号和引号的匹配逻辑
            }
        }
        return stack.isEmpty();
    }
}

修复说明

  • 移除引号分支末尾多余的stack.push(c);,避免重复入栈
  • 删除引号分支中stack.isEmpty()就返回false的判断,允许JSON以引号开头(即单独的字符串值)
  • 合并{和[的入栈逻辑,简化代码
  • 简化}和]的判断逻辑,合并空栈检查和匹配检查

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:55:38