在 ABAP 中,Java 的 finally 关键字等价于什么?
In ABAP, what is the equivalent of Java's finally keyword?
在Java中,finally
关键字用于执行代码(与异常一起使用-try..catch
语句)无论是否抛出异常(source).
例如:
try {
// this code might throw an exception
riskyCall();
// this code will only run if no exception was thrown above
mainProgram();
}
finally {
// this code will always run
cleanUp();
}
ABAP 中是否有等效的功能?如果不是,实现相同功能的惯用方法是什么?
我知道 ABAP 有一个 CLEANUP
关键字,但这似乎只有在抛出异常时才会执行。
我进行了试验并发现了以下可能的解决方案。不幸的是,我想不出没有代码重复的任何解决方案。
METHOD risky_method.
TRY.
WRITE 'code before...'.
IF lv_error_condition = abap_true.
RAISE EXCEPTION TYPE cx_foo.
ENDIF.
WRITE 'Main program...'.
WRITE 'Cleanup...'.
CLEANUP.
WRITE 'Cleanup...'.
ENDTRY.
ENDMETHOD.
METHOD outer_scope.
TRY.
risky_method( ).
CATCH cx_foo INTO DATA(lx_foo).
WRITE 'Caught the error!'.
ENDTRY.
ENDMETHOD.
对于lv_error_condition
等于abap_false
的情况,执行方法outer_scope
的输出是:
code before... Main program... Cleanup...
对于lv_error_condition
等于abap_true
的情况,输出为:
code before... Cleanup... Caught the error!
此解决方案的优点是清理始终运行。它的缺点是需要一些代码重复,因为清理需要编写两次。如果清理被打包到一个方法中,那么它就不是可怕的代码重复量。 :-/
ABAP 没有 Java finally
块的确切等价物。
有一个 TRY
... CLEANUP
结构,乍一看很相似,但实际上工作起来却大不相同:
METHOD buggy_method.
TRY.
WRITE 'code before the error...'.
RAISE EXCEPTION TYPE cx_foo.
WRITE 'This line will not get executed.'.
CLEANUP.
WRITE 'Cleanup...'.
ENDTRY.
ENDMETHOD.
" ...on an outer scope...
TRY.
buggy_method( ).
CATCH cx_foo INTO DATA(lx_foo).
WRITE 'Caught the error!'.
ENDTRY.
输出:code before the error... Cleanup... Caught the error!
然而,清理块并不总是*得到执行。它仅在出现异常时执行,并且该异常 not 由同一 TRY
块中的 CATCH
处理。这个想法是将它用于清理,清理应该在外部级别的 TRY
块处理异常时发生。因此,无论您是否有错误,它对于您想要 运行 的代码都没有用。它仅对您想要 运行 的代码有用,以防出现 try 块无法自行处理的错误。
涵盖 Java finally
块的一些用例的另一个功能是 resumable exceptions:
" In the class definiton
METHODS buggy_method RAISING RESUMABLE(cx_foo).
" In the class implementation:
METHOD buggy_method.
WRITE 'code before the error...'.
RAISE RESUMABLE EXCEPTION TYPE cx_foo.
WRITE 'code after the error....'.
ENDMETHOD.
" Somewhere else:
TRY.
buggy_method( ).
CATCH BEFORE UNWIND cx_foo INTO DATA(lx_foo).
WRITE 'Caught the error!'.
RESUME.
ENDTRY.
输出:code before the error... Caught the error! code after the error....
CATCH
块末尾的 RESUME
关键字导致在异常 RAISE RESUMABLE
d 后立即继续执行。因此,如果您想确保即使在出现错误的情况下也能执行方法的结尾,那么这可能就是您正在寻找的语法。
* 是的,我知道有一些奇特的边缘情况,其中 Java 中的 finally-block 不会被执行。这些与这里无关。
一位同事给了我解决方案。避免代码重复,同时仍然允许异常向上传播的技巧是根本不使用 CLEANUP
关键字,而是:
- 在有风险的代码之后,捕获异常
CX_ROOT
(捕获所有可能的异常,而不仅仅是您期望的异常!)
- 运行
finally
风格的清理代码
- 使用
IS BOUND
查看是否引发异常,如果是,则重新引发
这是一个例子:
METHOD risky_method.
TRY.
WRITE 'code before...'.
IF lv_error_condition = abap_true.
RAISE EXCEPTION TYPE cx_foo.
ENDIF.
WRITE 'Main program...'.
CATCH cx_root INTO DATA(lx_root).
ENDTRY.
WRITE 'Cleanup...'.
IF lx_root IS BOUND.
RAISE lx_root.
ENDIF.
ENDMETHOD.
METHOD outer_scope.
TRY.
risky_method( ).
CATCH cx_foo INTO DATA(lx_foo).
WRITE 'Caught the error!'.
ENDTRY.
ENDMETHOD.
对于lv_error_condition
等于abap_false
的情况,输出为:
code before... Main program... Cleanup...
对于lv_error_condition
等于abap_true
的情况,输出为:
code before... Cleanup... Caught the error!
在Java中,finally
关键字用于执行代码(与异常一起使用-try..catch
语句)无论是否抛出异常(source).
例如:
try {
// this code might throw an exception
riskyCall();
// this code will only run if no exception was thrown above
mainProgram();
}
finally {
// this code will always run
cleanUp();
}
ABAP 中是否有等效的功能?如果不是,实现相同功能的惯用方法是什么?
我知道 ABAP 有一个 CLEANUP
关键字,但这似乎只有在抛出异常时才会执行。
我进行了试验并发现了以下可能的解决方案。不幸的是,我想不出没有代码重复的任何解决方案。
METHOD risky_method.
TRY.
WRITE 'code before...'.
IF lv_error_condition = abap_true.
RAISE EXCEPTION TYPE cx_foo.
ENDIF.
WRITE 'Main program...'.
WRITE 'Cleanup...'.
CLEANUP.
WRITE 'Cleanup...'.
ENDTRY.
ENDMETHOD.
METHOD outer_scope.
TRY.
risky_method( ).
CATCH cx_foo INTO DATA(lx_foo).
WRITE 'Caught the error!'.
ENDTRY.
ENDMETHOD.
对于lv_error_condition
等于abap_false
的情况,执行方法outer_scope
的输出是:
code before... Main program... Cleanup...
对于lv_error_condition
等于abap_true
的情况,输出为:
code before... Cleanup... Caught the error!
此解决方案的优点是清理始终运行。它的缺点是需要一些代码重复,因为清理需要编写两次。如果清理被打包到一个方法中,那么它就不是可怕的代码重复量。 :-/
ABAP 没有 Java finally
块的确切等价物。
有一个 TRY
... CLEANUP
结构,乍一看很相似,但实际上工作起来却大不相同:
METHOD buggy_method.
TRY.
WRITE 'code before the error...'.
RAISE EXCEPTION TYPE cx_foo.
WRITE 'This line will not get executed.'.
CLEANUP.
WRITE 'Cleanup...'.
ENDTRY.
ENDMETHOD.
" ...on an outer scope...
TRY.
buggy_method( ).
CATCH cx_foo INTO DATA(lx_foo).
WRITE 'Caught the error!'.
ENDTRY.
输出:code before the error... Cleanup... Caught the error!
然而,清理块并不总是*得到执行。它仅在出现异常时执行,并且该异常 not 由同一 TRY
块中的 CATCH
处理。这个想法是将它用于清理,清理应该在外部级别的 TRY
块处理异常时发生。因此,无论您是否有错误,它对于您想要 运行 的代码都没有用。它仅对您想要 运行 的代码有用,以防出现 try 块无法自行处理的错误。
涵盖 Java finally
块的一些用例的另一个功能是 resumable exceptions:
" In the class definiton
METHODS buggy_method RAISING RESUMABLE(cx_foo).
" In the class implementation:
METHOD buggy_method.
WRITE 'code before the error...'.
RAISE RESUMABLE EXCEPTION TYPE cx_foo.
WRITE 'code after the error....'.
ENDMETHOD.
" Somewhere else:
TRY.
buggy_method( ).
CATCH BEFORE UNWIND cx_foo INTO DATA(lx_foo).
WRITE 'Caught the error!'.
RESUME.
ENDTRY.
输出:code before the error... Caught the error! code after the error....
CATCH
块末尾的 RESUME
关键字导致在异常 RAISE RESUMABLE
d 后立即继续执行。因此,如果您想确保即使在出现错误的情况下也能执行方法的结尾,那么这可能就是您正在寻找的语法。
* 是的,我知道有一些奇特的边缘情况,其中 Java 中的 finally-block 不会被执行。这些与这里无关。
一位同事给了我解决方案。避免代码重复,同时仍然允许异常向上传播的技巧是根本不使用 CLEANUP
关键字,而是:
- 在有风险的代码之后,捕获异常
CX_ROOT
(捕获所有可能的异常,而不仅仅是您期望的异常!) - 运行
finally
风格的清理代码 - 使用
IS BOUND
查看是否引发异常,如果是,则重新引发
这是一个例子:
METHOD risky_method.
TRY.
WRITE 'code before...'.
IF lv_error_condition = abap_true.
RAISE EXCEPTION TYPE cx_foo.
ENDIF.
WRITE 'Main program...'.
CATCH cx_root INTO DATA(lx_root).
ENDTRY.
WRITE 'Cleanup...'.
IF lx_root IS BOUND.
RAISE lx_root.
ENDIF.
ENDMETHOD.
METHOD outer_scope.
TRY.
risky_method( ).
CATCH cx_foo INTO DATA(lx_foo).
WRITE 'Caught the error!'.
ENDTRY.
ENDMETHOD.
对于lv_error_condition
等于abap_false
的情况,输出为:
code before... Main program... Cleanup...
对于lv_error_condition
等于abap_true
的情况,输出为:
code before... Cleanup... Caught the error!