定義引用變量Reference Variables
引用變量存儲的是某個對象的地址,而不是實際的內容。ABAP中的引用包括數據引用與對象引用,因此,ABAP中有數據引用變量與對象引用變量兩種,而對象引用又分為類引用與接口引用。
數據引用使用CREATE DATA...創建數據對象,對象引用使用CREATE OBJECT...創建類對象,但定義都使用DATA ... TYPE REF TO...的方式來聲明一個引用變量(指針)。
數據引用就是指對非對象如基本變量、結構體、內表變量的引用(類似C中的指針)。對象引用指的是對象ABAP語言中的對象進行引用(類似Java中的指針)。
創建數據引用變量的數據類型:
TYPES <t_dref> TYPE REF TO DATA.
使用上面創建出來的引用變量數據類型或者是直接通過下面的語句來創建數據引用變量:
DATA <dref> TYPE REF TO DATA.
DATA數據類型為通用類型,這里還可以使用其他通用類型或具體的類型。
動態創建數據對象Creating Data Objects Dynamically
以前在程序的聲明部分通過DATA語句定義都是靜態的數據對象,它們在程序運行前就已經存在了。如果想在程序運行期間動態的創建數據對象,則需要使用數據引用變量來動態的創建:
CREATE DATA <dref> TYPE <type>|LIKE <obj>.
該語句創建出一個數據對象,並使用 dref 指向它。與C中的指針一樣,如果要訪問該對象內容,則一定先要進行解引操作。注意:<dref>一定要先通過上面DATA...TYPE REF TO ... 語句定義過數據引用變量,這里只是創建與分配。另外,type還可以是動態指定的:
CREATE DATA <dref> TYPE (<name>).
TYPES : typ TYPE c LENGTH 1.
DATA: dref TYPE REF TO typ.
"類型可以是動態指定
CREATE DATA dref TYPE ('TYP') .
dref->* = 'A'.
WRITE: / dref->*."A
TYPES : typ2 TYPE REF TO typ.
DATA: dref2 TYPE REF TO typ2."指向指針的指針
CREATE DATA dref2 .
DATA: dref3 TYPE REF TO typ2.
dref3 = dref2."指向同一東西
DATA: c VALUE 'A'.
GET REFERENCE OF c INTO dref2->*.
WRITE: / dref3->*->*."A
TYPES: tabtyp TYPE i OCCURS 0,line TYPE LINE OF tabtyp.
DATA: wa TYPE LINE OF tabtyp.
DATA: dref TYPE REF TO tabtyp.
CREATE DATA dref LIKE TABLE OF wa."注:TABLE OF 后面接的是內表的行類型
"CREATE DATA dref TYPE TABLE OF i."也可以是這樣
"CREATE DATA dref TYPE TABLE OF line."也可以是這樣
APPEND 1 TO dref->*.
LOOP AT dref->* INTO wa.
WRITE: wa.
ENDLOOP.
獲取數據對象引用Getting References to Data Objects
將已存在的某數據對象分配給已定義好的數據引用變量:
GET REFERENCE OF <obj> INTO <dref>.
注意:<dref>一定要先通過上面DATA...TYPE REF TO ... 語句定義過數據引用變量,這里只是獲取與分配。這里的數據對象obj 可以是通過DATA定義的數據對象(如基本內置數據類型變量),也可以是某字段符號,或者甚至還可以是DATA ... TYPE REF TO...定義的引用變量(此時相當於二級指針,請參考下面示例):
DATA dref TYPE REF TO string."第一步:定義
DATA dref2 TYPE REF TO DATA.
field-SYMBOLS <fs>.
field-SYMBOLS <fs1>.
field-SYMBOLS <fs2>.
CREATE DATA dref TYPE ('STRING')."第二步:創建
"因為定義時已經明確指定了數據類型,所以可以省略TYPE選項
*CREATE DATA dref.
ASSIGN dref->* to <fs2>."第三步:使用
<fs2> = 'ABCD'.
"dref2相當於二級指針
GET REFERENCE OF dref INTO dref2.
"要區分與上面的區別,下面這樣直接賦值屬於指針拷貝,
"結果是dref2與dref同指向同一個數據對象,此情況下的dref2則不是二級指針了
*dref2 = dref.
ASSIGN dref2->* to <fs>."第一次解引用
ASSIGN <fs>->* to <fs1>."第二次解引用
WRITE : / <fs1>.
ABCD
注意:不要將局部對象的引用傳到其他過程中或不要引用局部對象,否則會出Java中不安全發布問題
可以將一個常量的地址分配給字段符號,但不能修改該常量的值:
DATA: e_i3 TYPE REF TO i .
GET REFERENCE OF 33 INTO e_i3.
field-SYMBOLS: <fs> TYPE i .
ASSIGN e_i3->* to <fs>.
<fs> = 100.
以上代碼運行時會報錯。
或者直接獲取某個非引用變量的地址:
DATA: dref TYPE REF TO i ,
i TYPE i VALUE 33.
GET REFERENCE OF i INTO dref.
dref->* = 44.
WRITE: i.
解引用Dereferencing Data References
要訪問數據引用(對象引用不需要)所指向的數據對象的內容,先一定要進行解引用操作(但不一定要將解引出來分配給字段符號后再能使用,可以直接使用解引用出來的內容,參看前面):
ASSIGN <dref>->* TO <FS> [CASTING ...].
DATA: dref TYPE REF TO i .
DATA: dref2 TYPE REF TO i .
CREATE DATA dref.基於基本數據類型創建數據對象
field-SYMBOLS: <fs>,<fs2>.
ASSIGN dref->* to <fs>.
<fs> = 100.
dref2 = dref.
ASSIGN dref2->* to <fs2>.
WRITE: / <fs2>.
100
但如果數據引用是一個指向某個結構的數據對象時,可以直接通過結構對象引用(指針)來訪問其成員,這與普通數據變量對象引用有所區別:
TYPES: BEGIN OF strc,
comp ,
END OF strc.
DATA ref TYPE REF TO strc.
CREATE DATA ref TYPE strc.
"可以直接使用結構引用(指針)訪問其成員
ref->comp = 'X'.
"也可這樣:先解引用結構對象,再訪問其成員,這也是標准訪問方式
"ref->*-comp = 'X'.
"通過指針直接進行訪問成員
WRITE: / ref->comp.
FIELD-SYMBOLS: <dref> TYPE strc.
ASSIGN ref->* TO <dref>.
"通過結構體對象本身來訪問成員
WRITE: / <dref>-comp.