乐趣区

关于sap:历史上的今天编程语言中null引用的十亿美元错误

这是 Jerry 2021 年的第 10 篇文章,也是汪子熙公众号总共第 281 篇原创文章。

明天是 2021 年 1 月 17 日,星期日,腊月初五。

Jerry 之前收到 CSDN 社区赠送的新年礼物,一本台历:《了不起的程序员》,

其中 1 月 16 日,17 日两天的篇幅,都在介绍托尼·霍尔(Tony Hoare), 计算机科学家,因程序设计语言定义与设计方面的杰出贡献取得 1980 年的图灵奖。疾速排序算法的发明者。

如果想查看用 ABAP 实现的 8 种排序算法的源代码,能够查看 Jerry 之前的文章:

Jerry 2017 年的五一小长假:8 种经典排序算法的 ABAP 实现

本文不会探讨霍尔创造的疾速排序算法,而是介绍另一个来自霍尔,现在依然被程序员在编程语言中宽泛应用的一个设计:null 援用。

null 援用被霍尔称为 ” 十亿美元谬误 ”,是霍尔 1965 年设计 ALGOL W 语言时提出的。

《Java 实战》中提到,在 Java 程序开发中应用 null 会带来实践和实际操作上的种种问题:

  • 它是谬误之源
  • 会使你的代码收缩
  • 本身毫无意义
  • 毁坏了 Java 的哲学
  • 在 Java 的类型零碎上开了口子

霍尔的名言:

我把它叫做我的“十亿美元谬误”,就是在 1965 年创造了空援用 …… 我无奈抵御放进一个空援用的引诱,仅仅是因为实现起来非常容易。

引入了空援用的编程语言,在拜访援用之前,须要显式查看援用是否无效。

Java

下图第 46 行代码定义的 print 办法,输出参数是一个类型为 Integer 的援用。在调用援用之前,须要先判断其是否是空援用,否则程序执行时就会呈现运行时异样。

ABAP

应用 CHECK X IS NOT INITIAL 进行进攻,如果 X 为空援用,则不会执行 CHECK 语句的下一条语句。

谨严的德国人,在霍尔传授 null 援用的根底上,又设计出 IS BOUND, IS NOT INITIAL 和 IS ASSIGNED 这几种判断逻辑:

SAP ABAP 一组关键字 IS BOUND, IS NOT INITIAL 和 IS ASSIGNED 的用法辨析

JavaScript

第 10 行的 print 办法外部,用 && 操作符的短路逻辑 (short-circuit) 个性来实现空援用的检测:如果传入的 oPrinter 是空援用,则不会执行 && 前面的 print 调用。

而 TypeScript 提供的可选链(Optional Chaining),则能够在语言层面优雅地防止这个问题。

上面的 TypeScript 代码,应用问号结构了一个可选链。如果 a 为空,则表达式 a?.b 间接返回 undefined 给变量 val,而不会试图去执行 a.b

上图 TypeScript 代码,编译之后生成的 JavaScript 代码如下图所示,咱们能够把 TypeScript 的可选链看成 JavaScript 用三元表达式实现的语法糖。

为了加重 Java 程序员每次应用援用之前,显式进行非空查看的工作量,Java 8 引入了一个新的工具类:Optional.

Optional 仅仅是一个不含任何业务逻辑的包裹类,其 value 字段指向了真正的业务类。

下图是一个应用 Optional 工具类的例子,第 11 行的 filter 办法,传入的是一个通过 Lambda Function 实现的过滤条件。这行语句的语义是,对 anotherName 蕴含的字符串,进行过滤操作,查看 another 实例的 value 字段存储的援用,是否满足过滤条件(字符串长度小于 6):

Optional.filter 办法,无论过滤条件是否满足,返回的类型均为 Optional,便于链式调用。

我第 10 行传入 Optional 对象的字符串,显然长度远远大于 6,所以 filter 办法返回一个新的 Optional 对象,其 value 字段为 null.

对于 filter 调用返回的 Optional 对象,咱们能够持续调用 orElse,设置一个默认值。下图第 14 行用 orElse 实现的逻辑,语义是:如果 shortName 包裹的 value 字段为空,则返回 orElse 办法传入的默认值。

Java 8 的 Optional 工具类并不像 TypeScript 的可选链一样,后者是语言层面提供的个性,而 Optional 仅仅是开发包里的一个工具类。

比方 Optional 的静态方法 of,其实现仅仅是新建一个 Optional 对象,去包裹传入的 value 援用:

orElse 办法,外部实现也是一个简略的三元表达式。

看这样一个极其的例子:

Outer 类有一个字段 nested,类型为 Nested 类。Nested 类有一个字段 inner,类型为 Inner 类。Inner 类蕴含了字段 foo,类型为 String,值为 Jerry:

如果想从 Outer 类的实例登程,写一段比拟强壮的代码,打印出深藏在 Inner 类里的 foo 字段,惯例的写法和应用 Optional 的写法别离位于下图 test1 和 test2 办法,大家能够比拟下,更喜爱哪一种?

值得一提的是,相似 Java Optional.orElse 办法,在 ABAP 里也存在基于语言层面的反对。

下图是 ABAP 740 的新语法:

下面的新语法,翻译成传统的 ABAP 代码如下:

由此可见,新的 ABAP 内表读取的语法比拟简洁,能少写 3 行代码。

然而新语法有一个缺点:如果 it_data 内表,不存在 object_ext 的值为 cl_crm_prodil_bo_names=>gc_prod_root 的记录,此时程序执行会被终止,抛出异样 CX_SY_ITAB_LINE_NOT_FOUND:

当然针对这种状况,ABAP 也有对应的解决方案。

下图测试代码第 17 行会抛出异样,而 19 行不会。从语义上容易了解:如果内表 lt_data 里不存在 name 为 Spring2 的记录,则返回开发者应用 DEFAULT VALUE 关键字指定的一个构造,作为默认值。

第 19 行执行结束后,构造 ls3 的 name 字段为 SpringInvalid, value 为 999.

本文从霍尔传授 1965 年提出的 null 援用作为切入点,向大家分享了 Jerry 工作中同空援用打交道的一些经验,感激浏览。

ABAP 专题

  • Jerry 的 ABAP, Java 和 JavaScript 乱炖
  • ABAP 开发人员将来应该学些什么
  • Jerry 2017 年的五一小长假:8 种经典排序算法的 ABAP 实现
  • Jerry 的 ABAP 原创技术文章合集
  • 300 行 ABAP 代码实现一个最简略的区块链原型
  • 应用 Java+SAP 云平台 +SAP Cloud Connector 调用 ABAP On-Premise 零碎里的函数
  • 在 SAP 云平台的 CloudFoundry 环境下生产 ABAP On-Premise OData 服务
  • ABAP vs Java,蛙泳 vs 自由泳
  • 聊聊 C 语言和 ABAP
  • 入手应用 ABAP Channel 开发一些小工具,晋升日常工作效率
  • 我用 ABAP 做过的那些无聊的事件
  • 不喜爱 SAP GUI?那试试用 Eclipse 进行 ABAP 开发吧
  • 应用 Visual Studio Code 编写和激活 ABAP 代码
  • 你的 ABAP 程序给佛祖开过光么?来试试 Jerry 这个小技巧
  • 在 SAP 云平台 ABAP 编程环境上编写第一段 ABAP 程序
  • SAP 官网公布的 ABAP 编程标准
  • ABAP Code Inspector 那些暗藏的性能,您都晓得吗?
  • 还在用 ABAP 进行 SAP 产品的二次开发?来理解下这种全新的二次开发理念吧
  • ABAP Netweaver 体内的那些寄生式编程语言
  • 从 SAP 社区上的一篇博客开始,聊聊 SAP 产品命名背地的那份情怀
  • 云端的 ABAP Restful 服务开发
  • 如何在 SAP 云平台 ABAP 编程环境里把 CDS view 裸露成 OData 服务
  • 应用 abapGit 在 ABAP On-Premises 零碎和 SAP 云平台 ABAP 环境之间进行代码传输
  • 30 分钟用 Restful ABAP Programming 模型开发一个反对增删改查的 Fiori 利用
  • Jerry 带您理解 Restful ABAP Programming 模型系列之二:Action 和 Validation 的实现
  • Jerry 带您理解 Restful ABAP Programming 模型系列之三:云端 ABAP 利用调试
  • SAP 云平台上的 ABAP 编程环境里如何生产第三方服务
  • ABAP 开发者上云的时候到了 – 当初大家能够收费应用 SAP 云平台 ABAP 环境的试用版了
  • 学而不思则罔 – SAP 云平台 ABAP 编程环境的由来和实用场景
  • SAP 云平台里的三叉戟利用
  • 如何基于 Restful ABAP Programming 模型开发并部署一个反对增删改查的 Fiori 利用
  • SAP 2019 TechEd Key Note 解读:云时代下 SAP 从业人员如何做二次开发?
  • 有哪些 ABAP 关键字和语法,到了 ABAP 云环境上就没方法用了?
  • ABAP 开发环境终于反对以驼峰命名法主动格式化 ABAP 变量名了
  • 利用 ABAP 740 的新关键字 REDUCE 实现一个理论工作工作
  • 一段让人瑟瑟发抖的 ABAP 代码
  • 昨日万圣节 ABAP 怪兽级代码谜团,颁布答案啦
  • 介绍一种在 ABAP 内核态进行内表高效拷贝的办法
  • 应用 SAP Cloud Application Programming 模型开发 OData 的一个理论例子
  • 当 ABAP 遇见普罗米修斯
  • 应用 ABAP 绘制可伸缩矢量图
  • ABAP 开发环境语法高亮的那些事儿
  • SAP 谬误音讯调试之七种武器:让所有的谬误音讯都能被定位
  • 应用 ABAP 操作 Excel 的几种办法
  • SAP GUI 里的收藏夹事务码管理工具
  • SAP GUI 和 Windows 注册表
  • 有了 Debug 权限就能干坏事?小心了,你的一举一动尽在系统监控中
  • ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX 这些东东是什么鬼
  • 实现 ABAP 条件断点的三种形式
  • 应用 SAT 跟踪监控从浏览器关上的 SAP 利用的性能和调用栈
  • 一个 13 年 ABAP 老兵的倡议:理解这些基础知识,对 ABAP 开发有百利而无一害
  • SAP ABAP Netweaver 容器化, 不可能实现的工作吗?
  • SAP 产品加强技术回顾
  • SAP API 开发方法大全
  • 浅谈 Java 和 SAP ABAP 的动态代理和动静代理,以及 ABAP 面向切面编程的尝试
  • SAP ABAP 应用服务器的 HTTP 响应状态码(Status Code)
  • SAP ABAP 里存在 Java List 这种汇合工具类么?CL_OBJECT_COLLECTION 理解一下
  • ABAP 面试题系列:写一组会呈现死锁 (Deadlock) 的 ABAP 程序
  • SAP ABAP Netweaver 服务器的规范登录形式解说
  • SAP ABAP 关键字语法图和 ABAP 代码主动生成工具 Code Composer
  • SAP ABAP SM50 的另类用处 – ABAP 工作过程对数据库表读取操作的检测
  • 对于 SAP ABAP 字符变量和字符串变量字符个数的一个知识点,和一个血案
  • SAP ABAP 一组关键字 IS BOUND, IS NOT INITIAL 和 IS ASSIGNED 的用法辨析
  • SAP ABAP 和 Java 里的弱援用 (WeakReference) 和软援用(SoftReference)
  • SAP AMDP 介绍 – ABAP 托管的 HANA 数据库过程
  • 给你的 ABAP 对象打上标签(Tag)

更多 Jerry 的原创文章,尽在:” 汪子熙 ”:

退出移动版