是否有一种有效的方法来避免实例化具有语法错误的类?

时间:2018-04-16 18:11:38

标签: sap abap

正如您所知,拥有包含语法错误的类的活动代码非常容易(有人激活代码忽略语法警告或有人更改了类调用的方法的签名)。

这意味着也可以通过

动态实例化这样的类
CREATE OBJECT my_object TYPE (class_name).

将失败,显然无法捕获SYNTAX_ERROR异常。目标是编写在发生这种情况时终止的代码。

已知解决方案:

  1. 将CREATE OBJECT语句包装在RFC函数模块中,调用目标为NONE的模块,然后从RFC调用中捕获(经典)异常SYSTEM_FAILURE。如果RFC成功,实际创建对象(您不能将创建的对象从RFC中传出,因为RFC函数模块不能传递引用,并且据我所知,对象不能通过引用传递。)

    这个解决方案不仅不够优雅,而且还会严重影响性能,因为RFC调用会产生全新的LUW。此外,您实际上并没有阻止SYNTAX_ERROR转储,只是让它转储到您不关心的线程中。它仍然会令人烦恼地出现在ST22中。

  2. 在尝试实例化类之前,请调用

    cl_abap_typedescr=>describe_by_name( class_name )
    

    并捕获它尝试描述的代码具有语法错误时抛出的基于类的异常CX_SY_RTTI_SYNTAX_ERROR。

    这比RFC变体好得多,但似乎仍然增加了不必要的开销 - 通常,我不想要describe_by_name返回的类型信息,我只是称它为获取可捕获的异常,当它成功时,它的结果就会被抛弃。

  3. 有没有办法在不增加此类开销的情况下阻止SYNTAX_ERROR转储?

1 个答案:

答案 0 :(得分:2)

我们想出的最有效的方法:

METHODS has_correct_syntax
  IMPORTING
    class_name    TYPE seoclsname
  RETURNING
    VALUE(result) TYPE abap_bool.

METHOD has_correct_syntax.
  DATA(include_name) = cl_oo_classname_service=>get_cs_name( class_name ).
  READ REPORT include_name INTO DATA(source_code).
  SYNTAX-CHECK FOR source_code MESSAGE DATA(message) LINE DATA(line) WORD DATA(word).
  result = xsdbool( sy-subrc = 0 ).
ENDMETHOD.

在加载程序和对其进行语法检查时仍然有很多开销。但是,至少没有其他用于编译您不感兴趣的描述符的方法。

我们调查了何时创建依赖管理器,该管理器在启动时将类连接在一起,并应排除语法错误的候选对象。

CS并不总是存在,因此get_cs_name可能会变空。似乎取决于NetWeaver版本和开发人员使用的编辑器。

如果确定语法错误是由类自己的代码引起的,则可能要考虑缓冲语法检查的结果,并且仅在上次检查类后更改类时才重新验证。如果您期望语法错误是由那些类之外的东西引起的,则此方法不起作用。