运行时类型服务 RTTS

运行时类型服务 RTTS (★★)

#abap-objects #rtts #rtti #rttc

概览表

项目 关键点
RTTI 运行时类型识别 — 查询类型属性
RTTC 运行时类型创建 — 动态创建类型
描述类层次 对应ABAP类型系统的类层次

RTTI (Run Time Type Identification)

RTTI 用于在运行时查询数据类型和对象类型的属性。

描述类层次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CL_ABAP_TYPEDESCR (根描述类,抽象)
│ DESCRIBE_BY_DATA( data ) → 获取数据类型描述
│ DESCRIBE_BY_OBJECT_REF( ref ) → 获取对象类型描述
│ DESCRIBE_BY_NAME( name ) → 通过名称获取描述
│ type_kind → 类型标识
│ absolute_name → 完整类型名

├── CL_ABAP_DATADESCR (数据类型)
│ ├── CL_ABAP_ELEMDESCR (基本类型)
│ ├── CL_ABAP_STRUCTDESCR (结构)
│ │ components → 组件表
│ ├── CL_ABAP_TABLEDESCR (内表)
│ └── CL_ABAP_REFDESCR (引用)

├── CL_ABAP_OBJECTDESCR (对象类型)
│ ├── CL_ABAP_CLASSDESCR (类)
│ │ attributes → 属性列表
│ │ methods → 方法列表
│ └── CL_ABAP_INTFDESCR (接口)

└── CL_ABAP_ENUMDESCR (枚举)

动态数据类型分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
" 分析结构类型
DATA: BEGIN OF ls_flight,
carrid TYPE sflight-carrid,
connid TYPE sflight-connid,
fldate TYPE sflight-fldate,
END OF ls_flight.

" 获取类型描述
DATA(lo_descr) = CAST cl_abap_structdescr(
cl_abap_typedescr=>describe_by_data( ls_flight ) ).

" 访问组件信息
LOOP AT lo_descr->components INTO DATA(ls_comp).
WRITE: / ls_comp-name, ls_comp-type_kind.
ENDLOOP.
📌Down-cast 必须操作
DESCRIBE_BY_DATA 返回 CL_ABAP_TYPEDESCR 类型引用。
需要用 CAST (或 ?=) down-cast 到具体子类才能访问特定属性。

动态对象类型分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
" 分析对象类型
METHOD on_vehicle_created FOR EVENT vehicle_created OF lcl_vehicle
IMPORTING sender.

" 获取 sender 的动态类型描述
DATA(lo_descr) = CAST cl_abap_classdescr(
cl_abap_typedescr=>describe_by_object_ref( sender ) ).

" 获取类名
DATA(lv_classname) = lo_descr->get_relative_name( ).

" 只处理 Bus
IF lv_classname = 'LCL_BUS'.
APPEND sender TO mt_vehicles.
ENDIF.
ENDMETHOD.

常用方法对比

方法 所属类 返回 用途
describe_by_data( data ) CL_ABAP_TYPEDESCR 类型描述 分析数据类型
describe_by_object_ref( ref ) CL_ABAP_TYPEDESCR 类描述 分析对象类型
describe_by_name( name ) CL_ABAP_TYPEDESCR 类型描述 通过名称获取
get_relative_name( ) CL_ABAP_OBJECTDESCR 类名 获取相对类名
components CL_ABAP_STRUCTDESCR 内表 结构组件列表

RTTC (Run Time Type Creation)

从 SAP Web AS 6.40 开始,可以动态创建类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
" 动态创建结构类型
DATA: lt_components TYPE cl_abap_structdescr=>component_table.

" 添加组件
APPEND VALUE #( name = 'CARRID' type = cl_abap_elemdescr=>get_c( 3 ) )
TO lt_components.
APPEND VALUE #( name = 'PRICE' type = cl_abap_elemdescr=>get_p( length = 15 decimals = 2 ) )
TO lt_components.

" 创建结构描述
DATA(lo_struct) = cl_abap_structdescr=>create( lt_components ).

" 创建数据引用
DATA: lo_data TYPE REF TO data.
CREATE DATA lo_data TYPE HANDLE lo_struct.

" 使用
FIELD-SYMBOLS: <ls_struc> TYPE any.
ASSIGN lo_data->* TO <ls_struc>.

RTTC 创建方法

方法 用途
CL_ABAP_ELEMDESCR get_c( len ), get_i( ), get_p( ) 创建基本类型
CL_ABAP_STRUCTDESCR create( components ) 创建结构类型
CL_ABAP_TABLEDESCR create( line_type ) 创建内表类型
CL_ABAP_REFDESCR create( base_type ) 创建引用类型

RTTI vs 替代方案

方法 优点 缺点
RTTI 类型安全,不触发异常 代码稍多
Down-cast + TRY 简单直接 可能触发运行时错误
DESCRIBE FIELD 简单 已过时,功能有限

考试/测试模式

场景/关键词 答案
“RTTI全称” Run Time Type Identification
“RTTC全称” Run Time Type Creation
“根描述类” CL_ABAP_TYPEDESCR
“describe_by_data返回什么” CL_ABAP_TYPEDESCR 引用,需要down-cast
“如何获取类名” get_relative_name( )
“动态创建类型用什么” RTTC,各描述类的 create( ) 方法
“RTTI替代DESCRIBE FIELD” 是的,RTTI覆盖了所有DESCRIBE功能