Skip to Content

Can you explain the ABAP doc for class constructor

Hello guys,

In the ABAP doc of "Constructors of classes", it is said that "static methods may be executed before the static constructor was ended". I don't understand, because IMHO it's essential that the static constructor is completely executed before the other static methods of the class. So, I don't understand at all what it means.

Any idea?

Thanks. Sandra.

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

3 Answers

  • Best Answer
    Aug 06, 2017 at 08:55 AM

    I can think of the scenario where you want to do lots of stuff in class_constructor, so that you split up the initialization process into several static methods that are called from class_constructor. When those methods are called, the class constructor has not finished execution yet.

    When accessing static methods from outside of class_constructor I agree the class_constructor should always have finished execution. Unless maybe the compiler is smart enough to know which static methods do not have side effects / are pure / do not access static members (but I'd prefer if it didn't).

    Add comment
    10|10000 characters needed characters exceeded

  • Aug 06, 2017 at 11:49 AM

    I thought of how you could "overtake" the class constructor so that is started but execution continues before it is finished. Kind of like how shared objects area constructors work. So I tried out parallel processing but of course each task that runs in parallel has its own internal mode and therefore each of them executes the class constructor individually... Mike's subclass class_constructor approach might be the solution.

    Anyways for reference :)

    REPORT z_fl_class_constructor_test.
    
    CLASS lcl_test DEFINITION.
      PUBLIC SECTION.
        CLASS-METHODS:
          class_constructor,
          static_method.
        CLASS-DATA:
          gt_output TYPE stringtab READ-ONLY.
      PROTECTED SECTION.
      PRIVATE SECTION.
        CLASS-DATA:
          gv_id TYPE ssi_session_key.
    ENDCLASS.
    
    CLASS lcl_test IMPLEMENTATION.
      METHOD class_constructor.
        DATA: lv_time TYPE timestampl.
        gv_id = NEW cl_session_info( )->get_session_key( ).
    
        GET TIME STAMP FIELD lv_time.
        APPEND |{ lv_time } { gv_id }: Class constructor started| TO gt_output.
    
        CALL FUNCTION 'RZL_SLEEP'.
    
        GET TIME STAMP FIELD lv_time.
        APPEND |{ lv_time } { gv_id }: Class constructor finished| TO gt_output.
      ENDMETHOD.
    
      METHOD static_method.
        DATA: lv_time TYPE timestampl.
        GET TIME STAMP FIELD lv_time.
        APPEND |{ lv_time } { gv_id }: Static method called| TO gt_output.
      ENDMETHOD.
    ENDCLASS.
    
    CLASS lcl_parallel DEFINITION INHERITING FROM cl_abap_parallel.
      PUBLIC SECTION.
        METHODS:
          do REDEFINITION.
      PROTECTED SECTION.
      PRIVATE SECTION.
    ENDCLASS.
    
    CLASS lcl_parallel IMPLEMENTATION.
      METHOD do.
        lcl_test=>static_method( ).
        EXPORT result = lcl_test=>gt_output TO DATA BUFFER p_out.
      ENDMETHOD.
    ENDCLASS.
    
    START-OF-SELECTION.
      DATA: gt_result TYPE stringtab.
    
      DATA(go_parallel) = NEW lcl_parallel( p_num_processes = 3  ).
      go_parallel->run( EXPORTING p_in_tab  = VALUE #( ( ) ( ) ( ) ( ) ( ) ( ) )
                        IMPORTING p_out_tab = DATA(gt_out) ).
    
      LOOP AT gt_out ASSIGNING FIELD-SYMBOL(<gs_out>).
        WRITE: / |{ <gs_out>-index } { <gs_out>-message } { <gs_out>-time }|.
        IMPORT result = gt_result FROM DATA BUFFER <gs_out>-result.
        LOOP AT gt_result ASSIGNING FIELD-SYMBOL(<gv_line>).
          WRITE: / <gv_line>.
        ENDLOOP.
        CLEAR gt_result.
      ENDLOOP.
    
    Add comment
    10|10000 characters needed characters exceeded

  • Aug 06, 2017 at 11:19 AM

    Interesting question. To my understanding it works as Fabian described, but it wouldn't need a smart compiler to handle this.

    In fact, I had a lengthy dive in to the behaviour of static subclasses which supports the dumb compiler theory, static methods really behave more like 'named bits of code'. See Determine class name used for calling a static method, example at Oct 24. To recap the relevant bit:

    class lcl_super definition. 
        class-methods foo returning value(result) type i. 
    endclass.
    
    class lcl_sub definition inheriting from lcl_super.
      class-methods class_constructor.
    endclass. 
    
    ...
    data(r1) = lcl_sub=>foo( ).    " <<<< lcl_sub class constructor will NOT be executed.
    

    Because statics are not inherited in ABAP, the compiler ignores the subclass completely in this case.

    From this I would infer that the compiler's logic is something like:

    some code calls static method foo_static in class cl_bar.
    if class_is_not_loaded( cl_bar ). 
      load cl_bar.
      execute cl_bar=>class_constructor.
    endif.
    execute method foo_static.

    So once the class constructor starts executing it is treated as an already loaded class requiring no further class constructors. But it is only once the class-constructor is finished that the class-external calls get executed.

    But that's just my deductions, I may be wrong.

    Add comment
    10|10000 characters needed characters exceeded