• [SAP ABAP开发技术总结]反射,动态创建内表、结构、变量


     

    其实ABAP中没有反射这一概念,这是从JAVA中来的,我只是个比喻。它也用于动态编程,比如来用动态的创建一个结构、内表等,虽然直接可以通过cl_alv_table_create=>create_dynamic_table的来动态创建一个内表,但在不借助于这些已有的方法时,我们该如何创建?

    1.14.     反射

    CL_ABAP_TYPEDESCR

      |--CL_ABAP_DATADESCR

      |   |--CL_ABAP_ELEMDESCR

      |   |--CL_ABAP_REFDESCR

      |   |--CL_ABAP_COMPLEXDESCR

      |       |--CL_ABAP_STRUCTDESCR

      |       |--CL_ABAP_TABLEDESCR

      |--CL_ABAP_OBJECTDESCR

         |--CL_ABAP_CLASSDESCR

         |--CL_ABAP_INTFDESCR

    DATA: structtype  TYPE REF TO cl_abap_structdescr.
    structtype ?= cl_abap_typedescr=>
    describe_by_name( 'spfli' ).

     

    DATA: datatype TYPE REF TO cl_abap_datadescr,
    field(5) TYPE c
    .
    datatype ?= cl_abap_typedescr=>describe_by_
    data( field ).

     

    DATA: elemtype TYPE REF TO cl_abap_elemdescr.
    elemtype = cl_abap_elemdescr=>
    get_i( ).
    elemtype = cl_abap_elemdescr=>
    get_c( 20 ).

     

    DATA: oref1 TYPE REF TO object.
    DATA: descr_ref1 TYPE REF TO cl_abap_typedescr.
    CREATE OBJECT oref1
    TYPE ('C1'). "C1为类名
    descr_ref1
    = cl_abap_typedescr=>describe_by_object_ref( oref1 ).

    还有一种:describe_by_data_ref

    1.14.1.           TYPE HANDLE

    handle只能是CL_ABAP_DATADESCR或其子类的引用变量只能用于Data类型,不能用于Object类型即不能用于CL_ABAP_ OBJECTDESCR所以没有:

    CREATE OBJECT dref TYPE HANDLE objectDescr.

     

    DATA: dref TYPE REF TO data,
    c10type
    TYPE REF TO cl_abap_elemdescr.
    c10type
    = cl_abap_elemdescr=>get_c( 10
    ).
    CREATE DATA dref TYPE HANDLE c10type.

    DATA: x20type TYPE REF TO cl_abap_elemdescr.
    x20type
    = cl_abap_elemdescr=>get_x( 20 ).
    FIELD-SYMBOLS: <fs> TYPE any
    .
    ASSIGN dref->* TO <fs> CASTING TYPE HANDLE x20type.

    1.14.2.           动态创建数据Data或对象Object

      TYPES: ty_i TYPE i.
     
    DATA: dref TYPE REF TO ty_i .

     
     CREATE DATA dref TYPE ('I')."根据基本类型名动态创建数据
      dref->* = 1.
     
    WRITE: / dref->*." 1

      CREATE OBJECT oref TYPE ('C1')."根据类名动态创建实例对象

    1.14.3.           动态创建基本类型变量、结构、内表

    DATA: dref_str TYPE REF TO data,
          dref_tab
    TYPE REF TO data,
          dref_i
    TYPE REF TO data,
      itab_type
    TYPE REF TO cl_abap_tabledescr,
      struct_type
    TYPE REF TO cl_abap_structdescr,
      elem_type
    TYPE REF TO cl_abap_elemdescr,
      table_type
    TYPE REF TO cl_abap_tabledescr,
      comp_tab
    TYPE cl_abap_structdescr=>component_table WITH HEADER LINE.
    FIELD-SYMBOLS :<fs_itab> TYPE ANY TABLE.

    **=========动态创建基本类型
    elem_type ?= cl_abap_elemdescr
    =>get_i( ).
    CREATE DATA
    dref_i TYPE HANDLE elem_type ."动态的创建基本类型数据对象

    **=========动态创建结构类型
    struct_type ?= cl_abap_typedescr
    =>describe_by_name( 'SFLIGHT' )."结构类型
    comp_tab[]
    = struct_type
    ->get_components( )."组成结构体的各个字段组件
    * 向结构中动态的新增一个成员
    comp_tab-name = 'L_COUNT'."为结构新增一个成员
    comp_tab-type = elem_type."新增成员的类型对象
    INSERT comp_tab INTO comp_tab INDEX 1.
    * 动态创建结构类型对象
    struct_type
    = cl_abap_structdescr
    =>create( comp_tab[] ).
    CREATE DATA
    dref_str TYPE HANDLE struct_type."使用结构类型对象来创建结构对象

    **=========动态创建内表
    * 基于结构类型对象创建内表类型对象
    itab_type = cl_abap_tabledescr
    =>create( struct_type ).
    CREATE DATA
    dref_tab TYPE HANDLE itab_type."使用内表类型对象来创建内表类型
    ASSIGN dref_tab->* TO <fs_itab>."将字段符号指向新创建出来的内表对象

    "**========给现有的内表动态的加一列
    table_type ?= cl_abap_tabledescr
    =>describe_by_data( itab ).
    struct_type ?= table_type
    ->get_table_line_type( ).
    comp_tab[]
    = struct_type
    ->get_components( ).
    comp_tab
    -name = 'FIDESC'.
    comp_tab
    -type = cl_abap_elemdescr
    =>get_c( 120 ).
    INSERT comp_tab INTO comp_tab INDEX 2.
    struct_type
    = cl_abap_structdescr
    =>create( comp_tab[] ).
    itab_type
    = cl_abap_tabledescr
    =>create( struct_type ).
    CREATE DATA
    dref_tab TYPE HANDLE itab_type.

    1.14.4.类对象反射

    CLASS c1 DEFINITION.
     
    PUBLIC SECTION.
       
    DATA: c VALUE 'C'.
       
    METHODS: test.
    ENDCLASS.

    CLASS c1 IMPLEMENTATION.
     
    METHOD:test.
       
    WRITE:/ 'test'.
     
    ENDMETHOD.
    ENDCLASS.
    START-OF-SELECTION.
     
    TYPES: ty_c.
     
    DATA: oref TYPE REF TO object .
     
    DATA: oref_classdescr TYPE REF TO cl_abap_classdescr .

     
    CREATE OBJECT oref TYPE ('C1')."根据类名动态创建实例对象
     
    "相当于Java中的Class类对象
      oref_classdescr ?= cl_abap_classdescr
    =>describe_by_object_ref( oref ).

     
    DATA: t_attrdescr_tab TYPE abap_attrdescr_tab WITH HEADER LINE,"类中的属性列表
            t_methdescr_tab
    TYPE abap_methdescr_tab WITH HEADER LINE."类中的方法列表
     
    FIELD-SYMBOLS <fs_attr> TYPE any.
      t_attrdescr_tab[]
    = oref_classdescr->attributes.
      t_methdescr_tab[]
    = oref_classdescr->methods.
     
    LOOP AT t_attrdescr_tab."动态访问类中的属性
       
    ASSIGN oref->(t_attrdescr_tab-name) TO <fs_attr>.
        WRITE: / <fs_attr>.
     
    ENDLOOP.
     
    LOOP AT t_methdescr_tab."动态访问类中的方法
       
    CALL METHOD oref->(t_methdescr_tab-name).
      ENDLOOP.
    image033

     
  • 相关阅读:
    js上拉加载下拉刷新
    CSRF
    Linux 常用命令
    汇编语言:了解寄存器与内存模型
    Node 的fs模块
    pdf转为html查看pdf.js
    centOs升级
    H5新特性监听手机的返回键
    gsap
    使用 iframe + postMessage 实现跨域通信
  • 原文地址:https://www.cnblogs.com/jiangzhengjun/p/4264644.html
Copyright © 2020-2023  润新知