当前位置: 首页 > news >正文

#SAP-ABAP:数据类型与数据对象(8篇) 第六篇:操作实践篇——数据对象的常用操作与异常处理方案

数据类型与数据对象(8篇)

第六篇:操作实践篇——数据对象的常用操作与异常处理方案

在前几篇中,我们详细讨论了数据类型的定义、底层存储、生命周期以及类型与实例的映射关系。理论储备充足后,本篇将回归实践,聚焦数据对象在日常开发中的高频操作:创建、拷贝、属性访问、类型转换等。同时,针对空指针、类型不匹配、属性不存在等常见异常,给出识别方法和处理方案,帮助你在实际编码中写出更健壮的代码。


一、数据对象的创建:静态与动态

1.1 静态创建(编译时确定类型)

最常规的创建方式,类型在编写代码时已知。

DATA: lv_num TYPE i VALUE 100, " 基本类型 ls_mara TYPE mara, " 字典结构 lt_mara TYPE TABLE OF mara. " 内表

特点:类型安全,编译器可检查;内存分配由系统自动管理(通常为栈或静态区)。

1.2 动态创建(运行时确定类型)

当类型只有在程序运行时才知道(例如根据用户输入的表名),可以使用动态创建。

DATA: lr_data TYPE REF TO data. FIELD-SYMBOLS: <fs_any> TYPE any. " 根据字符串类型的类型名创建数据对象 CREATE DATA lr_data TYPE ('ZMY_STRUCT'). ASSIGN lr_data->* TO <fs_any>.

异常风险:如果类型名不存在或未激活,CREATE DATA会抛出异常CX_SY_CREATE_DATA_ERROR

安全处理

TRY. CREATE DATA lr_data TYPE (lv_typename). CATCH cx_sy_create_data_error INTO DATA(lx_ex). MESSAGE '类型不存在或无效' TYPE 'E'. ENDTRY.

二、数据对象的拷贝:深拷贝与浅拷贝

2.1 值类型的拷贝——独立副本

对于基本类型、结构体、固定长度字符串等值类型,赋值操作会创建独立的数据副本,修改一个不影响另一个。

DATA: a TYPE i VALUE 10, b TYPE i. b = a. " 拷贝值 a = 20. " a 改变,b 仍为 10

2.2 引用类型的拷贝——共享对象

引用变量赋值时,拷贝的是引用(地址),两个变量指向同一数据对象。

DATA: r1 TYPE REF TO i, r2 TYPE REF TO i. CREATE DATA r1. r1->* = 10. r2 = r1. " 拷贝引用 r1->* = 20. WRITE r2->*. " 输出 20

2.3 字符串与内表的拷贝——值语义(含写时复制)

ABAP 中的STRING和内表在语义上是值类型,即赋值会产生独立副本。但底层实现采用了写时复制(Copy-on-Write)优化,以提升性能。

DATA: s1 TYPE string VALUE `Hello`, s2 TYPE string. s2 = s1. " s2 和 s1 暂时共享同一内存(引用计数=2) s2 = s2 && ` World`. " 修改时触发复制,s1 不受影响

开发注意:在大多数场景下,你可以安全地将字符串和内表当作值类型使用,无需担心意外共享修改。

2.4 深层拷贝(完全独立副本)

对于复杂嵌套结构(如内表包含结构,结构内又有内表),简单的=可能只拷贝顶层,内部表仍共享。此时需要深层拷贝。

方法一:使用CL_ABAP_CONV_IN_CE等转换类,或手动递归复制。
方法二:通过序列化/反序列化实现克隆(效率较低)。

" 简单示例:使用 MOVE 对应字段(适用于结构体中有内表的情况,需自行处理) ls_copy = ls_original. " 对于包含内表的结构体,内表会独立复制(ABAP 默认深层复制结构体内表)

验证:对于自定义深度的嵌套,可以通过ASSERT检查内表句柄是否不同,但通常 ABAP 的=对结构体已经做了深层复制(前提是结构体字段类型为内表时,会创建新的内表实例)。


三、属性访问与异常处理

3.1 对象属性访问

对于类实例,通过->访问属性(需使用 Getter/Setter 或直接公开字段)。

lo_person->set_name( '张三' ). lv_name = lo_person->get_name( ).

空引用异常:如果对象引用未初始化(INITIAL),访问方法会抛出CX_SY_REF_IS_INITIAL

DATA: lo_obj TYPE REF TO zcl_some_class. TRY. lo_obj->do_something( ). CATCH cx_sy_ref_is_initial. MESSAGE '对象未实例化' TYPE 'E'. ENDTRY.

安全做法:使用IS BOUND判断。

IF lo_obj IS BOUND. lo_obj->do_something( ). ELSE. " 处理未绑定情况 ENDIF.

3.2 动态访问字段符号

使用ASSIGN将字段符号指向数据对象的内存区域,然后通过<fs>读写。

FIELD-SYMBOLS: <fs_val> TYPE any. ASSIGN lv_num TO <fs_val>. IF <fs_val> IS ASSIGNED. <fs_val> = 200. ENDIF.

异常ASSIGN失败时,<fs_val>不会被分配。后续使用前应检查IS ASSIGNED

3.3 属性不存在(动态结构访问)

当使用ASSIGN COMPONENT动态访问结构体的字段时,字段名可能拼写错误或不存在。

DATA: ls_struct TYPE mara. FIELD-SYMBOLS: <fs_field> TYPE any. ASSIGN COMPONENT 'MATNR' OF STRUCTURE ls_struct TO <fs_field>. IF sy-subrc = 0. " 存在 ELSE. " 字段不存在 ENDIF.

常见陷阱:字段名大小写敏感(ABAP 数据字典中的字段名通常大写)。使用动态访问时务必注意。


四、类型转换:显式与隐式

4.1 隐式转换(自动)

ABAP 允许在某些情况下的隐式类型转换,但可能带来精度丢失或运行时错误。

DATA: lv_int TYPE i, lv_char TYPE c LENGTH 10. lv_char = '123'. lv_int = lv_char. " 隐式转换:字符 '123' -> 整数 123 lv_char = lv_int. " 隐式转换:整数 123 -> 字符 ' 123'(右对齐)

危险场景:将非数字字符赋给数字变量会触发运行时错误CX_SY_CONVERSION_NO_NUMBER

lv_char = 'ABC'. lv_int = lv_char. " 运行时错误

4.2 显式转换(安全)

推荐使用显式转换函数,便于异常处理。

  • CONV操作符(ABAP 7.40+):

    lv_int = CONV i( lv_char ).

    如果转换失败,仍会抛出异常,可结合CATCH使用。

  • NUMBER/CHAR转换

    TRY. lv_int = CONV i( lv_char ). CATCH cx_sy_conversion_no_number. MESSAGE '不能转换为数字' TYPE 'E'. ENDTRY.
  • CL_ABAP_CONV_IN_CE:更灵活的转换工具。

4.3 内表与结构体的转换

使用MOVE-CORRESPONDINGCORRESPONDING操作符实现字段名匹配的转换。

DATA: ls_source TYPE ty_source, ls_target TYPE ty_target. ls_target = CORRESPONDING #( ls_source ).

异常:如果字段名不完全匹配,需要显式映射或使用EXCEPT选项排除部分字段。


五、常见操作异常汇总与处理

异常类型触发场景识别方法处理方案
空引用访问调用未实例化的对象方法IF lo_obj IS BOUND提前实例化或给出提示
类型转换错误将非数字字符串赋给数字变量TRY ... CATCH cx_sy_conversion_no_number校验输入格式,使用NUMBER等转换函数
字段不存在ASSIGN COMPONENT动态访问结构体时字段名错误检查sy-subrc是否为 0验证字段名字典存在性,或使用CL_ABAP_STRUCTDESCR获取字段列表
内表索引越界READ TABLE ... INDEXLOOP AT ... INDEX超出范围检查sy-subrcLINES( lt_itab )先判断LINES( lt_itab ) >= idx
哈希表键值缺失READ TABLE ... WITH TABLE KEY读取不存在的键sy-subrc <> 0或使用ASSIGN配合IS ASSIGNED允许不存在时用默认值或提示
动态创建类型失败CREATE DATA type (lv_typename)中类型名不存在CATCH cx_sy_create_data_error检查类型名或 fallback 为默认类型
除法或算术溢出计算结果超出类型范围CATCH cx_sy_arithmetic_overflow使用更大范围类型(如P长度增加)或预判

六、健壮代码实践建议

6.1 防御性编程

  • 访问对象前检查IS BOUND;使用字段符号前检查IS ASSIGNED
  • 动态类型创建使用TRY-CATCH包裹。
  • 类型转换使用显式函数 + 异常捕获,不依赖隐式转换。

6.2 使用系统提供的诊断工具

  • sy-subrc捕获内表操作、数据库访问等的返回码。
  • CATCH SYSTEM-EXCEPTIONS(旧式)不建议使用;优先使用基于类的异常。

6.3 日志与错误记录

当异常发生时,记录必要的上下文信息(变量值、类型名、调用栈),便于事后分析。

CATCH cx_sy_conversion_no_number INTO DATA(lx_ex). DATA(lv_msg) = lx_ex->get_text( ). WRITE: / '转换异常:', lv_msg. " 可写入自定义日志表 ENDTRY.

6.4 单元测试覆盖异常路径

为关键操作编写单元测试(ABAP Unit),模拟异常条件,确保异常处理代码被正确触发。

METHOD test_empty_object. DATA: lo_obj TYPE REF TO zcl_dummy. TRY. lo_obj->do_it( ). cl_aunit_assert=>fail( '异常未触发' ). CATCH cx_sy_ref_is_initial. " 预期异常,测试通过 ENDTRY. ENDMETHOD.

七、总结

操作类型常见风险推荐应对
对象创建动态类型不存在使用TRY-CATCH,提供回退
拷贝引用共享导致副作用明确值拷贝与引用拷贝语义;必要时深层克隆
属性访问空引用,字段不存在IS BOUND检查,sy-subrc判断
类型转换格式错误,精度丢失显式转换 + 异常捕获,避免依赖隐式转换

数据对象的操作几乎渗透到每一行ABAP代码中。掌握这些常见操作的正确姿势和异常处理技巧,能够显著提升程序的健壮性和可维护性。下一篇将进入进阶优化篇,探讨基于数据类型与对象的性能优化技巧。

📌下篇预告:进阶优化篇——基于类型与对象特征的性能优化技巧

作者:你的编程学习伙伴
版本记录:2026年5月

💬 你在实际开发中是否遇到过因类型转换错误或空引用导致的生产事故?欢迎分享你的排查经验。

http://www.jsqmd.com/news/855364/

相关文章:

  • 08-实战:RuoYi-Vue项目的自动化发布
  • YOLOv5到v8,哪个更适合你的表情识别项目?我用同一份数据集做了次全面对比评测
  • STM32G431时钟树配置避坑指南:从CubeMX图形化到代码实战,手把手教你调出80MHz主频
  • 2026年兰州景观亮化靠谱厂家TOP5:兰州建筑亮化、兰州建筑泛光照明、兰州文旅亮化、兰州旅游景区亮化、兰州景观泛光照明选择指南 - 优质品牌商家
  • Fluent瞬态计算踩坑记录:时间统计采样设置里的3个关键细节与避坑指南
  • 基于STM32F105系列使用CAN总线实现双机通信代码
  • eNSP实验避坑指南:华为路由器IP地址配完却Ping不通?这5个细节检查了吗?
  • 2026年Q2广州宠物犬舍猫舍评测:四家连锁机构深度对比 - 优质品牌商家
  • 告别理论!用Python可视化带你彻底搞懂电机插补算法(逐点比较法)
  • 从零搭建企业级网络准入:用Agile Controller-Campus + 华为交换机实战802.1X认证
  • RK3588工业一体机:异构计算、AI推理与Linux系统构建实战
  • 2026年工业门应用白皮书:兰州工业提升门/兰州工业滑升门/兰州工业翻板门/兰州工业车间门/兰州工业钢木门/兰州工业钢质门/选择指南 - 优质品牌商家
  • 2026嵌入式晾衣架实测评测:落地晾衣架、语音晾衣架、遥控晾衣机、阳台晾衣架、隐藏式晾衣架、伸缩晾衣架、全自动晾衣架选择指南 - 优质品牌商家
  • SAP-ABAP:数据类型与数据对象(8篇) 第七篇:进阶优化篇——基于类型与对象特征的性能优化技巧
  • 从Matlab仿真到上板验证:手把手完成Xilinx DDS多项数据生成的全流程
  • HarmonyOS 图片缩放没想象中简单——detailEnhance 四档质量深度解析
  • 告别理论推导!用Python+NumPy手撸一个卡尔曼滤波器(附AR序列预测完整代码)
  • 从‘Hello World’到自主导航:一个ROS1节点的完整生命周期与调试指令全记录
  • 别再乱调JVM堆大小了!Elasticsearch内存配置的5个实战避坑点
  • LabVIEW事件驱动状态机:从原理到实战的混合编程架构解析
  • 2026四川全屋定制打印机实力厂家排行及地址汇总:高温彩釉打印机/700度高温烧结打印机/uv光油墨水/排行一览 - 优质品牌商家
  • 双目立体视觉实战:SAD、SSD与SGBM算法原理与OpenCV调优指南
  • STC8H的PWM除了调光还能干啥?一个呼吸灯代码带你窥探电机控制与信号捕获
  • 数字化转型最大的谎言:上了低代码就能“降本增效”?
  • 2026届必备的十大降重复率平台解析与推荐
  • MyBatis 执行流程与延迟加载原理
  • 3岁孩子能不能喝花姐八珍粉?怎么控制用量?
  • SAP-ABAP:数据类型与数据对象(8篇) 第八篇:误区避坑篇——数据类型与对象操作的常见误区解析
  • 别再一个个置位了!博图PLC编程效率翻倍:SET_BF指令结合ARRAY的进阶玩法
  • FreeRTOS信号量实战:从同步互斥原理到嵌入式并发编程避坑指南