尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

114、 实例与静态成员:从一次诡异的“共享数据”事故说起

114、 实例与静态成员:从一次诡异的“共享数据”事故说起 114、 实例与静态成员:从一次诡异的“共享数据”事故说起那是一个周四下午,生产系统的Z报表突然报出数据错乱。用户说同一张订单号在列表里出现了两行,金额还不一样。我远程连上去,ST22里没有dump,SE38里单步执行逻辑也没问题——直到我注意到一个被我无视了很久的细节:那个报表里用了一个全局类,类的属性在初始化时被填充,然后每个用户跑出来的结果居然会互相串。当时脑子里第一个反应是“不可能”。ABAP对象默认每个会话独立,实例数据怎么可能跨用户共享?直到我翻开那个类的定义,看到DATA声明里没加INSTANCE,而是直接放在了CLASS-DATA段。问题就出在这——我把本该是实例属性的变量,写成了类的静态属性。更绝的是,这代码是三个月前我自己写的,注释还写着“这里缓存一下提高性能”。那一瞬间,什么性能,什么优雅,全变成了打脸。静态成员在所有实例之间共享一份数据,这本来是个非常强大的工具,但用错了地方,就是生产事故的温床。今天咱们就借这个坑,把实例成员和静态成员彻底聊透。先看最基础的区分。在ABAP里,一个类内部可以有两类属性、方法和事件:实例成员属于每个具体的对象实例,用DATA、METHODS、EVENTS声明,不带CLASS-前缀;静态成员属于类本身,用CLASS-DATA、CLASS-METHODS、CLASS-EVENTS声明。实例成员必须先CREATE OBJECT再通过对象引用访问,静态成员直接用类名加=就能碰,连实例都不用建。举个例子,你写一个“订单处理”类,里面有个实例属性gv_order_number,那每个对象实例都有自己的gv_order_number。但如果你把声明换成CLASS-DATA gv_order
返回列表