数据类型与数据对象 (★★★)
#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. 是无效的。泛型仅用于为形式参数(USING、CHANGING)和字段符号(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...ENDMODULE 内部或事件块内部的 DATA 语句创建的是全局数据对象,不是局部的。这是常见的 bug 来源。应在程序开头声明所有全局数据。
ABAP Objects 中的可见性(属性)
| 可见性区域 |
可访问范围 |
| Private |
仅同类的方法 |
| Protected |
同类的方法 + 子类 |
| Public |
任何外部调用者 |
数据对象的生命周期
| 数据对象 |
生命周期 |
| 全局数据对象 |
程序在内存中期间 |
| 对象属性 |
从实例化到最后一个引用被删除 |
| 局部数据对象(过程中) |
所在模块化单元的生命周期 |
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(尾部空格保留) |
相关笔记