This is a test message to test the length of the message box.
Login
ABAP FINAL
Created by Software-Heroes

ABAP - FINAL

1544

In this article, we'll take a look at the new FINAL language construct, how it works, and what you can do with it.



With the ABAP release for the cloud, a few new language constructs have appeared in ABAP. We want to take a look at one of these new constructs today.

 

Introduction

Now what is FINAL actually about, especially since the keyword already exists in the context of class definitions? Maybe the name isn't very well chosen, but FINAL is about defining variables, just like DATA. However, variables are created whose value can only be set once, after which all changing accesses are prohibited.

 

Variables

In the first examples, let's create a few variables and take a look at the general syntax. You'll notice that it can be used in the same places as DATA:

FINAL(ld_name) = `My name is John`.

FINAL(lt_partner) = VALUE tt_partner(
  ( partner = '1' name = 'Partner One' )
  ( partner = '2' name = 'Partner Two' )
).

 

In the example shown, we create a string and a table whose values we preassign.

 

Tables

In the next example we look at processing with tables. To do this, we fill our table with a SELECT and define it directly when reading with FINAL. This fills the table with data, but it cannot be changed afterwards. Then let's try different types of loops:

SELECT FROM zbs_dmo_partner
  FIELDS *
  INTO TABLE @FINAL(lt_partner).

LOOP AT lt_partner INTO DATA(ls_partner) FROM 1 TO 3.
ENDLOOP.

LOOP AT lt_partner REFERENCE INTO DATA(lr_partner) FROM 1 TO 3.
ENDLOOP.

 

Reading the data works without any problems, the loops also work without errors. As long as you don't try to change the data in the second loop, there will be no error.

 

Loop

In the next example, let's look at the loop and using FINAL in a loop. To do this, we fill the table once with dummy data, the table was declared with DATA and could therefore be changed. Then we implement two loops, one where the workspace is defined with FINAL and one where we make a copy with FINAL.

DATA(lt_partner) = VALUE tt_partner(
  ( partner = '1' name = 'Partner One' )
  ( partner = '2' name = 'Partner Two' )
  ( partner = '3' name = 'Partner Three' )
  ( partner = '4' name = 'Partner Four' )
).

LOOP AT lt_partner INTO FINAL(ls_final_partner).
ENDLOOP.

LOOP AT lt_partner INTO DATA(ls_partner).
  FINAL(ls_copy) = ls_partner.
ENDLOOP.

 

Loops work without problems, running through the FINAL statement multiple times is no problem. It is important that the variable is only set at one point with FINAL. If this point is run through several times, the content of the variable changes.

 

CHANGING

The last example in this article deals with passing such defined variables to methods with changing parameters. The following example is not possible and cannot be activated even if the variable in the method is not changed:

FINAL(ls_partner) = VALUE ts_partner( partner = '3' name = 'Partner Three' ).

changing_final_variable(
  CHANGING
    cs_partner = ls_partner
).

 

Error

In some of the examples shown, activation of source code is already not possible because the system recognizes that the field is being changed and the compiler prevents activation:

 

In the case of the loop with reference, the compiler allows activation and does not show any errors. However, when you run the code, you get an uncatchable MOVE_TO_LIT_NOTALLOWED_NODATA exception:

SELECT FROM zbs_dmo_partner
  FIELDS *
  INTO TABLE @FINAL(lt_partner).

LOOP AT lt_partner REFERENCE INTO DATA(lr_partner) FROM 1 TO 3.
  lr_partner->street = 'Dummy'.
ENDLOOP.

 

Complete example

As always, at the end of the article, once again the complete example of today's article. We took the table from the data model for the CDS views:

CLASS zcl_bs_demo_langu_final DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

    TYPES:
      BEGIN OF ts_partner,
        partner TYPE zbs_dmo_partner-partner,
        name    TYPE zbs_dmo_partner-name,
        country TYPE zbs_dmo_partner-country,
      END OF ts_partner,
      tt_partner TYPE SORTED TABLE OF ts_partner WITH UNIQUE KEY partner.

  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      set_variables
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      select_from_table
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      final_in_loop
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      call_method_with_changing
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      changing_final_variable
        CHANGING
          cs_partner TYPE ts_partner.
ENDCLASS.


CLASS zcl_bs_demo_langu_final IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    set_variables( out ).
    select_from_table( out ).
    final_in_loop( out ).
    call_method_with_changing( out ).
  ENDMETHOD.


  METHOD set_variables.
    FINAL(ld_name) = `My name is John`.
    io_out->write( ld_name ).

    FINAL(lt_partner) = VALUE tt_partner(
      ( partner = '1' name = 'Partner One' )
      ( partner = '2' name = 'Partner Two' )
    ).
    io_out->write( lt_partner ).

*    INSERT VALUE #( partner = '3' name = 'Partner Three' ) INTO TABLE lt_partner.
  ENDMETHOD.


  METHOD select_from_table.
    SELECT FROM zbs_dmo_partner
      FIELDS *
      INTO TABLE @FINAL(lt_partner).

    LOOP AT lt_partner INTO DATA(ls_partner) FROM 1 TO 3.
      io_out->write( ls_partner ).
    ENDLOOP.

    LOOP AT lt_partner REFERENCE INTO DATA(lr_partner) FROM 1 TO 3.
      " Will dump
*      lr_partner->street = 'Dummy'.
    ENDLOOP.
  ENDMETHOD.


  METHOD final_in_loop.
    DATA(lt_partner) = VALUE tt_partner(
      ( partner = '1' name = 'Partner One' )
      ( partner = '2' name = 'Partner Two' )
      ( partner = '3' name = 'Partner Three' )
      ( partner = '4' name = 'Partner Four' )
    ).

    LOOP AT lt_partner INTO FINAL(ls_final_partner).
      io_out->write( ls_final_partner ).
    ENDLOOP.

    LOOP AT lt_partner INTO DATA(ls_partner).
      FINAL(ls_copy) = ls_partner.
      io_out->write( ls_copy ).
    ENDLOOP.
  ENDMETHOD.


  METHOD call_method_with_changing.
    FINAL(ls_partner) = VALUE ts_partner( partner = '3' name = 'Partner Three' ).

*    changing_final_variable(
*      CHANGING
*        cs_partner = ls_partner
*    ).
  ENDMETHOD.


  METHOD changing_final_variable.
    " No implementation
  ENDMETHOD.
ENDCLASS.

 

Conclusion

Today's statement expands your knowledge of defining variables. The naming is a matter of taste and not necessarily consistent. In the end, you can use it to provide values and tables that also come with write protection and you don't have to worry about making adjustments in subroutines.

 

Source:
SAP Documentation - FINAL


Included topics:
New ABAPFINAL
Comments (0)



And further ...

Are you satisfied with the content of the article? We post new content in the ABAP area every Friday and irregularly in all other areas. Take a look at our tools and apps, we provide them free of charge.


ABAP - XCO Strings

Category - ABAP

In this article we look at the XCO class for generating and processing strings for ABAP Cloud and compare it with the classic statements.

11/22/2024

ABAP - XCO Libraries

Category - ABAP

What can you do with the library in ABAP and ABAP Cloud and how do you use the objects the best way? Find out more here.

11/12/2024

ABAP - Type Casting

Category - ABAP

How do you actually get the original type of a class or instance if it is passed in a generic table? In this article we examine the possibilities.

04/16/2024

ABAP - RETURN value

Category - ABAP

After all these years, the “real” return in ABAP has finally arrived. In this article we will show you how it works and what it can do.

02/13/2024

ABAP Deep Dive - FOR (Loops)

Category - ABAP

Let's take a closer look at the FOR loop. How does it work? What do I have to consider and what can I do with it?

04/14/2023