正如您所知,拥有包含语法错误的类的活动代码非常容易(有人激活代码忽略语法警告或有人更改了类调用的方法的签名)。
这意味着也可以通过
动态实例化这样的类CREATE OBJECT my_object TYPE (class_name).
将失败,显然无法捕获SYNTAX_ERROR异常。目标是编写在发生这种情况时不终止的代码。
已知解决方案:
将CREATE OBJECT语句包装在RFC函数模块中,调用目标为NONE的模块,然后从RFC调用中捕获(经典)异常SYSTEM_FAILURE。如果RFC成功,实际创建对象(您不能将创建的对象从RFC中传出,因为RFC函数模块不能传递引用,并且据我所知,对象不能通过引用传递。)
这个解决方案不仅不够优雅,而且还会严重影响性能,因为RFC调用会产生全新的LUW。此外,您实际上并没有阻止SYNTAX_ERROR转储,只是让它转储到您不关心的线程中。它仍然会令人烦恼地出现在ST22中。
在尝试实例化类之前,请调用
cl_abap_typedescr=>describe_by_name( class_name )
并捕获它尝试描述的代码具有语法错误时抛出的基于类的异常CX_SY_RTTI_SYNTAX_ERROR。
这比RFC变体好得多,但似乎仍然增加了不必要的开销 - 通常,我不想要describe_by_name
返回的类型信息,我只是称它为获取可捕获的异常,当它成功时,它的结果就会被抛弃。
有没有办法在不增加此类开销的情况下阻止SYNTAX_ERROR转储?
答案 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版本和开发人员使用的编辑器。
如果确定语法错误是由类自己的代码引起的,则可能要考虑缓冲语法检查的结果,并且仅在上次检查类后更改类时才重新验证。如果您期望语法错误是由那些类之外的东西引起的,则此方法不起作用。