美文网首页SAP
被很多人误解的 ABAP 关键字:READ-ONLY

被很多人误解的 ABAP 关键字:READ-ONLY

作者: 华山令狐冲 | 来源:发表于2024-08-05 10:11 被阅读0次

本文阅读目录

READ-ONLY 的准确含义

READ-ONLY 的使用场合

READ-ONLY 的使用陷阱

总结

对很多 ABAP 开发人员来说,READ-ONLY 是一个使用频率不高的关键字。

因为用的不多,再加上这个关键字的字面意思,很容易让人误解。

本文通过具体的例子讲解,给大家澄清对于 READ-ONLY 的理解误区。

ABAP 里的 READ-ONLY, 只能用来修饰类的公有属性。

如果我们选中类的某个 private 属性,勾上其 Read-Only 选项然后试图激活,会收到语法错误提示:

addition READ-ONLY is only allowed for the public attributes of a class.

当然,在类的范畴之外的其他任意位置,比如 SE38 的 ABAP 报表,SE37 的 Function Module 里,也无法使用该关键字来修饰一般的 ABAP 变量。

READ-ONLY 的准确含义

SAP 官方文档里,对 READ-ONLY 关键字的定义:

  1. 只用于定义 ABAP 类的公有属性。
  2. READ ONLY 属性可以被任意消费者读取。
  3. READ ONLY 属性,可以在定义该属性的类,子类和友元类内部被修改。

看下面这个简单的类,其公有属性 name,被 READ-ONLY 修饰,初始值为 Jerry.

CLASS zcl_readonly_test DEFINITION
  PUBLIC FINAL CREATE PUBLIC .

  PUBLIC SECTION.
    CLASS-DATA name TYPE string READ-ONLY VALUE 'Jerry'.
    CLASS-METHODS work .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS ZCL_READONLY_TEST IMPLEMENTATION.
  METHOD work.
    name = 'Tom'.
  ENDMETHOD.
ENDCLASS.

下面是该类的消费代码。

WRITE:/ zcl_readonly_test=>name.

zcl_readonly_test=>work( ).

WRITE:/ zcl_readonly_test=>name.

作为该类的消费者,两次打印 name 属性,发现值从 Jerry 变成了 Tom.

有了 SAP 帮助文档的铺垫,对于这种行为也就不觉得奇怪了:READ-ONLY 属性的只读特性,只是相对于类的消费者而言的。

其值在类,子类和友元类的实现体内,仍然可以修改。

因为 name 属性值在类的方法 work 内进行了修改,所以前后两次 WRITE 语句打印的结果有所差异。

如果想在类,子类和友元类的外部修改 READ-ONLY 属性,会收到语法错误:

Write access to the READ-ONLY attribute is not allowed outside the class/interface.

READ-ONLY 的使用场合

从最后实现的效果看,如果不考虑继承的场景,被 READ-ONLY 所修饰的 public 属性,等价于类的实现者,为其提供了 public get 访问方法的 private 属性。

比如下面例子里的 Public READ-Only name 和 Private name1 属性,从使用效果上来说等价。

从表面上看,public READ-ONLY 属性,和 private 属性相比,可以少实现一个 get 方法。

那么这两种等价的方法,性能上有没有差异呢?

下面这篇博客,作者做了测试,结论是访问 READ-ONLY 属性,其耗费时间只有显式调用 get 方法的 30% 左右。

这个结论是合理的。因为在编程语言里,面向对象编程领域里的类方法调用,较之传统的 primitive 变量读取访问,本来就要付出额外的开销。

不过这些额外的开销,相比于 ABAP 应用程序花费在数据库层面或网络层面执行逻辑的耗费时间,几乎可以忽略不计。

https://zevolving.com/2011/02/read-only-attribute-vs-getter-methods/

READ-ONLY 的陷阱

SAP 帮助文档也强调,READ-ONLY 并不能阻止其公有属性的引用值,通过引用传递的方式,在类的外部被修改其实际内容。

听起来是否觉得有些拗口?

笔者之前的 ABAP 开发教程,曾经详细介绍了 ABAP 里引用变量本身的值,和引用变量指向实际内存区域值的辨析。

用现实生活中的例子来说明。

我们住的公寓好比内存区域。引用变量本身的值,好比是一个个房间的门牌号,比如 301 代表三楼一号。引用变量指向实际内存区域的值,好比该房间内的住户。

我们把前面的例子稍作修改。

公有属性 name,如今类型不再是 String,而是指向 String 类型的引用,再加上 Read-Only 修饰。


这个语义类比成现实生活中的例子,即"房间的门牌号,不允许被修改"。比如某房间的门牌号为 301,不允许被修改为其他的门牌号,比如 302, 401 之类。

然后在类的构造函数里,给 name 引用指向的实际内存区域的值,赋上初始值 Jerry.

在类的实现体外部,我们试图把 name 属性值,赋给另外一个指向 String 的引用变量 lv,遇到期望中的语法错误:

Write access to the READ-ONLY attribute "NAME" is not allowed outside the class/interface.


但是该只读引用指向的实际内存区域的值,仍然可以在类的外部被修改。

下面的代码,两次打印 READ-ONLY 属性 name 指向的值,第一次打印类内部赋予的初始值 Jerry,第二次打印类外部被修改的新值 Tom.

FIELD-SYMBOLS: <name> TYPE string.

WRITE:/ zcl_readonly_test=>name->*.

ASSIGN zcl_readonly_test=>name->* TO <name>.
<name> = 'Tom'.

WRITE:/ zcl_readonly_test=>name->*.

这就好比房间的门牌号,不能被修改。但是房间里面具体住的人,已经变了。

总结

正因为 READ-ONLY 关键字,会在一定程度上给不明真相的使用者带来理解上的偏差,以及它无法避免引用型的公有属性,其指向的实际内容在类的外部被修改,因此 SAP Clean ABAP 编程规范里针对该关键字的建议是:谨慎使用

希望本文能澄清大家对 READ-ONLY 的理解,避免踩一些不必要的坑。

相关文章

  • SAP ABAP基本语法

    ABAP基本语法 基本语法.01-语句 ABAP源程序由注释和ABAP语句组成。 ABAP中的每个语句都以关键字开...

  • SAP ABAP语法基础

    ABAP语法基础 一、ABAP语法结构 1.每条ABAP语句均以关键字开头,以实心句号(.)结束;2.ABAP的格...

  • ABAP基本

    定义数据类型用关键字 TYPES.定义数据对象用关键字 DATA. 变量 在abap程序中用abap基本数据类型(...

  • ABAP和Java SpringBoot的单元测试

    ABAP 在ABAP类里,本地类(Local Class)里用关键字FOR TESTING声明过的方法, 在单元测...

  • ABAP数据类型定义

    1、ABAP-基本数据类型 2、ABAP-变量声明 根据类型定义变量使用关键字 "DATA" 声明变量:DATA ...

  • ABAP语法

    1.语句结构 ABAP中,所有程序语句都由一个ABAP语句关键字引导,并由一个句号" . " 作为结束的标志。 其...

  • SAP ABAP一组关键字 IS BOUND, IS NOT I

    ABAP里的IS BOUND, IS NOT INITIAL和IS ASSIGNED这组关键字,如果平时不留心,很...

  • 在SAP CAL(Cloud Application Libra

    https://cal.sap.com/ 根据关键字ABAP搜索: 在结果里选择SAP NetWeaver AS ...

  • 当我被误解

    相信很多人都被误解过,我也不例外。被家人误解,我可以大呼小叫的竭力澄清。被朋友误解,我可以尽力辩屈。被陌生...

  • ABAP基础一

    ABAP中的每个语句都以关键字开头,以句点结尾,ABAP不区分大小写。 注释 内联注释可以通过以下两种方法之一在程...

网友评论

    本文标题:被很多人误解的 ABAP 关键字:READ-ONLY

    本文链接:https://www.haomeiwen.com/subject/mymzhjtx.html