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

Delphi「Invalid class type cast」错误解决:统计JSON数组元素数

解决Delphi中JSON数组统计的「Invalid class type cast」错误

错误原因

你遇到的「Invalid class type cast」错误,核心问题是接口返回的JSON根结构是对象(TJSONObject),而非数组(TJSONArray)。你的JSONArrayCovertCnt函数直接将整个JSON字符串解析后强制转为TJSONArray,这种类型转换必然失败,触发错误。

解决方案

1. 修复JSONArrayCovertCnt函数

正确逻辑是先解析根对象,再从中提取data字段对应的数组:

function JSONArrayCovertCnt(usJSON: string): integer;
var
  JSONObj : TJSONObject;
  JSONArray : TJSONArray;
begin
  usJson := StringReplace(usJSON,'\"','"',[rfReplaceAll]);
  // 先解析为根对象
  JSONObj := TJSONObject.ParseJSONValue(usJSON) as TJSONObject;
  try
    if Assigned(JSONObj) then
    begin
      // 取出data字段对应的数组
      JSONArray := JSONObj.GetValue<TJSONArray>('data');
      Result := IfThen(Assigned(JSONArray), JSONArray.Count, 0);
    end
    else
      Result := 0;
  finally
    JSONObj.Free; // 释放对象,避免内存泄漏
  end;
end;

2. 优化主函数代码(避免重复解析+修复循环越界)

你在Button1Click中已经解析过一次JSON,没必要重复调用函数解析字符串。直接从已有的JSONValue中提取数组更高效,同时修复硬编码循环范围的问题:

procedure TForm1.Button1Click(Sender: TObject);
var
  stream: TStringStream;
  idHttpObj: TIdHTTP;
  JSONValue : TJSONValue;
  i : integer;
  JSONArray  : TJSONArray;
  resultCnt : integer; // 重命名变量,避开关键字冲突
begin
  stream := TStringStream.Create('', TEncoding.UTF8);
  try
    idHttpObj := TIdHTTP.Create(nil);
    try
      idHttpObj.Get(Url, stream);
    finally
      idHttpObj.Free;
    end;

    JSONValue := TJSONObject.ParseJSONValue(stream.DataString);
    try
      memo1.Clear;

      if JSONValue is TJSONObject then
      begin
        // 获取data数组
        JSONArray := (JSONValue as TJSONObject).GetValue<TJSONArray>('data');
        if Assigned(JSONArray) then
        begin
          // 动态循环数组所有元素,避免硬编码导致越界
          for i := 0 to JSONArray.Count - 1 do
          begin
            Memo1.Lines.Add('year: ' + JSONValue.GetValue<string>('data['+i.ToString+'].year') + '년');
            Memo1.Lines.Add('hshld: ' + JSONValue.GetValue<string>('data['+i.ToString+'].hshld') + ' 가구');
            Memo1.Lines.Add('popltn: ' + JSONValue.GetValue<string>('data['+i.ToString+'].popltn_sm') + '명');
            Memo1.Lines.Add('popltn_male: ' + JSONValue.GetValue<string>('data['+i.ToString+'].popltn_male') + '명');
            Memo1.Lines.Add('popltn_female: ' + JSONValue.GetValue<string>('data['+i.ToString+'].popltn_female') + '명');
            Memo1.Lines.Add('hshld_avrgpopltn: ' + JSONValue.GetValue<string>('data['+i.ToString+'].hshld_avrgpopltn') + '명');
            Memo1.Lines.Add('────────────────────────────────────');
          end;

          resultCnt := JSONArray.Count;
        end
        else
          resultCnt := 0;

        // 输出其他响应字段
        Memo1.Lines.Add('resultCode: ' + JSONValue.GetValue<string>('resultCode'));
        Memo1.Lines.Add('resultMsg: ' + JSONValue.GetValue<string>('resultMsg'));
        Memo1.Lines.Add('numOfRows : ' + JSONValue.GetValue<string>('numOfRows'));
        Memo1.Lines.Add('totalcount: ' + JSONValue.GetValue<string>('totalCount'));

        edit1.Text := IntToStr(resultCnt);
      end;
    finally
      JSONValue.Free; // 释放解析后的JSON对象
    end;
  finally
    stream.Free;
  end;
end;

额外注意事项

  • 内存管理:所有通过ParseJSONValue创建的JSON对象必须手动调用Free释放,防止内存泄漏。
  • 空值检查:访问数组或字段前,务必用Assigned判断是否为空,避免空指针异常。
  • 循环逻辑:不要硬编码循环范围,利用数组Count动态适配返回结果长度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 01:54:21