首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

手寫 JSON 解析器:從 C# 移植到 Java 的踩坑實錄與完整實作

     編輯:Java 綜合教學

前言:為什麼要造輪子?

因專案需求將 C# 的 CYQ.Data V5 移植至 Java,發現兩語言雖語法相似,但執行細節差異極大,不得不重寫核心組件。本文記錄移植過程中遇到的 10 大語言差異,並完整展示自製 JSON 解析器的三大核心類與測試代碼。

C# → Java 十大語言差異速查

C# 特性Java 替代方案
ref 參數(引用傳遞,可改變呼叫端引用)無直接對應;改用包裝類、陣列或回傳新物件
out 參數(多重回傳)改回傳陣列、Collection 或自訂 Result 物件
SqlDbType / DbTypeJDBC 使用 java.sql.Types 常數
DBNull.Value直接用 null;PreparedStatement 用 setNull()
Convert.ChangeType 通用轉型自寫工具類或用 Apache Commons BeanUtils
反射判斷泛型 IsGenericType、Nullable.GetUnderlyingType用 Type / ParameterizedType 檢查;無 nullable 基礎型別概念
Map 預設排序僅 LinkedHashMap 保持插入順序
代碼摺疊 #region需安裝外掛,改用 //region 註解
internal 組件可見性Java 無對應;只能用 package-private 或 public
其他大小寫、方法命名差異逐一適配

核心實作三類

1. CharState — 字元狀態機

追蹤 JSON 解析過程中的巢狀層級、鍵值階段、引號模式、轉義字元等狀態。

package cyq.data.tool;

class CharState {
    boolean jsonStart = false;
    boolean setDicValue = false;
    boolean escapeChar = false;
    boolean arrayStart = false;
    boolean childrenStart = false;
    int state = -1;        // 0:取名稱中, 1:取值中
    int keyStart = -1;     // -1未初始化, 0未開始, 1無引號, 2單引號, 3雙引號
    int valueStart = -1;
    boolean isError = false;

    void CheckIsError(char c) { /* 依字元檢查語法錯誤 */ }
}

2. JsonSplit — 核心解析邏輯

  • IsJson(str):快速判斷字串是否合法 JSON
  • Split(json):將 JSON 物件拆解為 List<LinkedHashMap<String,String>>,保留欄位順序
  • GetValueLength():遞迴計算巢狀值長度(處理物件/陣列嵌套)
  • SetCharState():逐字元狀態機驅動,識別 { } [ ] : , " ' 等關鍵字元

關鍵設計:

  1. 使用 LinkedHashMap 保證欄位順序
  2. 支援非嚴格模式(鍵名可無引號)
  3. 單次遍歷 + 遞迴下潛,時間複雜度 O(n)

3. JsonHelper — 對外門面

public class JsonHelper {
    public static boolean IsJson(String json) { return JsonSplit.IsJson(json); }
    public static Map<String,String> Split(String json) { /* 取第一個 Map */ }
    public static List<LinkedHashMap<String,String>> SplitArray(String jsonArray) { /* 陣列轉多筆 Map */ }
}

單元測試驗證

測試涵蓋:標準 JSON、無引號鍵名、巢狀物件/陣列、null 值、轉義字元等場景。結果證明解析器能正確處理常見結構,並優雅降級處理非標準輸入。

總結與感悟

「雖然 Java 很原始,C# 很高級,但技術走向極端後,也得學學大閘蟹,得橫著走。只有兩手抓、兩手都硬,才不會被技術所孤立。」

造輪子過程雖痛苦,卻能深入理解語言本質與資料結構。完整代碼已開源於專案 cyq.data.tool 套件,歡迎參考改進。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved