数据类型与数据对象

数据类型与数据对象 (★★★)

#abap-basics #data-types

数据类型 vs. 数据对象

概念 描述 占用内存?
数据类型 仅是描述;不与内存地址关联
数据对象 数据类型的实例;运行时占用内存

数据对象使用 DATA 语句定义。类型静态绑定,运行时不可更改。

1
2
3
4
DATA: lv_name  TYPE string,           "完整预定义类型
lv_count TYPE i, "完整预定义类型
lv_price TYPE p LENGTH 8 DECIMALS 2, "不完整类型 + 长度
lv_code TYPE c LENGTH 3. "不完整类型 + 长度

ABAP 预定义类型

完整类型(无需指定长度)

类型 类别 长度 初始值 说明
i 数值型 4 字节 0 整数
f 数值型 8 字节 0 二进制浮点数
decfloat16 数值型 8 字节 0 十进制浮点数(16位)
decfloat34 数值型 16 字节 0 十进制浮点数(34位)
d 字符型 8 字符 00000000 日期(YYYYMMDD)
t 字符型 6 字符 000000 时间(HHMMSS)
string 字符型 可变 长度 0 变长字符串
xstring 字节型 可变 长度 0 变长字节串

不完整类型(需指定长度)

类型 类别 默认长度 初始值 说明
p 数值型 8 0 压缩数字;使用 DECIMALS 指定小数位
n 字符型 1 0...0 数字文本
c 字符型 1 ' ... '(空格) 文本字段
x 字节型 1 X'00...0' 十六进制字段
📌不完整类型的长度指定
不完整类型必须补充长度。有两种语法形式:
1
2
3
4
" 短格式(括号中的长度)
DATA lv_text(10) TYPE c.
" 扩展格式(LENGTH 附加项,6.10 起可用)
DATA lv_text TYPE c LENGTH 10.

ABAP 泛型

泛型不能完全定义数据对象的属性。它们不能用于通过 DATA 声明数据对象。它们仅用于为形式参数和字段符号指定类型。

泛型 描述 覆盖范围
any 任意数据类型 所有类型
data 任意数据类型(与参数的 any 相同) 所有类型
simple 基本类型 + 平坦结构 i, f, p, decfloat, d, t, c, n, x, string, xstring, 平坦结构
csequence 类字符序列 c, string
numeric 数值类型 i, f, p, decfloat16, decfloat34
clike 类字符型 c, string, d, t, n
xsequence 类字节序列 x, xstring
c 文本字段(泛型长度) 任意长度的 c
n 数字文本(泛型长度) 任意长度的 n
x 十六进制字段(泛型长度) 任意长度的 x
decfloat 十进制浮点数 decfloat16, decfloat34
any table 任意内表 标准、排序、哈希
index table 支持索引访问的表 标准、排序
standard table 标准表 仅标准表
sorted table 排序表 仅排序表
table 标准表(遗留) 仅标准表
object 任意对象引用 所有对象引用
⚠️泛型不能声明数据对象
DATA lv_val TYPE any.无效的。泛型仅用于为形式参数(USINGCHANGING)和字段符号(FIELD-SYMBOLS)指定类型。

类型来源:局部 vs. 全局

来源 定义位置 作用域 示例
ABAP 预定义类型 ABAP 运行时环境 内置 i, string, p
全局数据类型 ABAP 字典 系统范围 数据元素、结构、表类型
局部数据类型 程序中的 TYPES 语句 仅限程序内部 TYPES: ty_price TYPE p LENGTH 10 DECIMALS 3.
💡全局(字典)类型的优势
  • 可跨程序复用
  • 语义文档(字段标签、帮助文本)
  • 自动与数据库表结构保持一致
  • 更改会传播到所有使用该类型的程序

数据对象类别

1
2
3
4
5
6
7
8
9
10
11
12
13
                    Data Objects
|
+--------------+--------------+
| | |
Elementary Structures Internal Tables
(单一值) (组件) (行类型 + 表体)
| | |
+----+----+ 可嵌套至任意深度 可包含
| | 结构或
Flat Deep 引用
(i,f,p, (string,
d,t,c, xstring,
n,x) 引用)
类别 描述 示例
基本类型 单一类型的值 DATA lv_name TYPE string.
结构 组件集合(可嵌套至任意深度) DATA ls_flight TYPE sflight.
内表 行的表格集合 DATA lt_flights TYPE TABLE OF sflight.
引用 指向数据对象或对象实例的指针 DATA lr_ref TYPE REF TO data.

平坦 vs. 深层数据对象

属性 平坦 深层
长度 静态(编译时固定) 动态(运行时变化)
引用其他对象
基本类型 i, f, p, d, t, c, n, x string, xstring, 引用
结构 所有组件都是平坦的 至少有一个深层组件
内存 内联存储 堆引用 + 数据
📌只要有一个深层组件,结构就是深层的
即使嵌套结构中只有一个组件是 string 或内表,整个结构也被归类为深层。必须同时考虑 Include 和子结构。

字面量

类型 语法 数据类型 长度 说明
数字字面量 123, -45 i(在范围内)或 p 固定 范围:-2^31+1 到 2^31-1 对应类型 i
文本字段字面量 'Hello World' c 1–255 字符 尾部空格被忽略;用 '' 表示单引号
字符串字面量 `Hello World` string 0–255 字符 尾部空格保留;6.10 起可用
💡转义引号
  • 文本字段字面量中的单引号:输入两次 – 'John''s book'
  • 字符串字面量中的反引号:输入两次
  • 无限制:字符串字面量中可用单引号,文本字段字面量中可用反引号

可见性与生命周期

传统 ABAP 中的可见性

声明位置 可见性 说明
FORM/ENDFORM 之间 子程序内部局部 遮蔽同名的全局变量
FUNCTION/ENDFUNCTION 之间 函数模块内部局部 遮蔽同名的全局变量
MODULE/ENDMODULE 之间 全局 常见陷阱 – 不是局部的!
事件块内部 全局 常见陷阱 – 不是局部的!
TABLES 语句(任何位置) 全局(即使在子程序中) 甚至在外部 PERFORM 中也跨程序可见
⚠️MODULE 和事件块中的 DATA 是全局的
MODULE...ENDMODULE 内部或事件块内部的 DATA 语句创建的是全局数据对象,不是局部的。这是常见的 bug 来源。应在程序开头声明所有全局数据。

ABAP Objects 中的可见性(属性)

可见性区域 可访问范围
Private 仅同类的方法
Protected 同类的方法 + 子类
Public 任何外部调用者

数据对象的生命周期

数据对象 生命周期
全局数据对象 程序在内存中期间
对象属性 从实例化到最后一个引用被删除
局部数据对象(过程中) 所在模块化单元的生命周期
STATICS 声明的局部变量 整个程序生命周期(可见性仍为局部)
💡STATICS 延长生命周期,不改变可见性
STATICS 可用于函数模块、子程序和静态方法。它使局部数据具有全局变量的生命周期,但保持其可见性限制在模块化单元内。

考试/测试模式

关键词 / 问题 答案
“哪些类型是完整的?” i, f, decfloat16, decfloat34, d, t, string, xstring
“哪些类型是不完整的?” p, n, c, x
“泛型可以声明数据对象吗?” 不可以 – 仅用于为参数和字段符号指定类型
“包含一个 string 组件的结构是平坦的还是深层的?” 深层 – 任何深层组件使整个结构变为深层
“MODULE 中的 DATA 在哪里可见?” 全局(陷阱题)
“FORM 中的 DATA 在哪里可见?” 子程序内部局部
“STATICS 的作用是什么?” 将生命周期延长至程序生命周期,保持局部可见性
“类型 c 的初始值是什么?” 空格(' '
“数值类型的初始值是什么?” 0
“数字字面量 10000000000 是什么类型?” p(超出 i 范围)
“‘text’ 和 `text` 有什么区别?” 'text' = 类型 c(尾部空格被删除);`text` = 类型 string(尾部空格保留)

相关笔记