Java和SAP ABAP的异常处理
Recently I am prepare an internal training and have been racking my brains to find a real example for my attendees about writting a “correct” program which gets rejected by compiler. The tricky point here is as a programmer, we always treat compiler as our god: if compiler complains that our program has errors, then we are wrong. Programmers tend to believe in that compiler will NEVER make mistakes.
Checked and unchecked exception in Java
Let’s see the following Java code:
package exception;
import java.sql.SQLException;
public class ExceptionForQuiz<T extends Exception> {
private void pleaseThrow(final Exception t) throws T {
throw (T) t;
}
public static void main(final String[] args) {
try {
new ExceptionForQuiz<RuntimeException>().pleaseThrow(new SQLException());
}
catch( final SQLException ex){
System.out.println("Jerry print");
ex.printStackTrace();
}
}
}
What result this program will generate?
Let’s analyze it step by step.
(1) The class ExceptionForQuiz uses a generic typing syntax extends to declare a bound that T only accepts Exception and its sub classes.
As a result in my main method code the creation of new ExceptionForQuiz via the below code is legal since according to JDK source code, RuntimeException is subclass of Exception.
new ExceptionForQuiz()
Also keep in mind that RuntimeException is a kind of Unchecked exception ( do not need to be declared in method where it might be raised ), which will be compared with ABAP exception later.
(2) According to Java Document, the type parameter in generic type declaration will be replaced by its bound during compile, in my exception RuntimeException will be replaced by Exception. This is called Type Erasure.
As a result, let’s forget about the try – catch for the moment.
This is original code:
This is the code decompiled from ExceptionForQuiz.class:
You can observe the fact of type erasure clearly.
You can also check the byte code by command javap, where the RuntimeException is erased.
(3) Now let’s see the result of this quiz.
The correct answer is: this program cannot pass compile! Compiler considers that SQLException could never have possibility to be raised from within TRY block.
Unfortunately, this is what I would like to do: raise SQLException via method pleaseThrow and catch it in catch block.
How to achieve my requirement?
Just change one line as highlighted below. Instead of catching SQLException, I now catch RuntimeException in order to pacify the compiler.
Now there is no compilation error any more but when executing it, I find the raised SQLException still cannot be caught as I expect. My println is not executed at all.
I have to catch the Exception, the super class of all other exception instead ( like CX_ROOT in ABAP ), which is not a good practice in exception handling area.
Handleable and Unhandleable Exception in ABAP
You can find both definition in ABAP help.
Let’s now do the similar exercise as we did previous in Java. Create a method with below signature.
Now make the first test:
DATA(lo_test) = NEW zcl_exception_test( ).
DATA: lo_exception TYPE REF TO cx_atd_exception.
CREATE OBJECT lo_exception.
WRITE:/ 'First test' COLOR COL_NEGATIVE.
TRY.
lo_test->please_throw( lo_exception ).
CATCH cx_atd_exception INTO DATA(exception1).
WRITE:/ 'Jerry: ' , exception1->get_text( ).
ENDTRY.
It works as expected, the raised exception is caught.
Now the second test:
DATA: lo_exception2 TYPE REF TO cx_sql_exception.
CREATE OBJECT lo_exception2.
WRITE:/ 'Second test' COLOR COL_NEGATIVE.
TRY.
lo_test->please_throw( lo_exception2 ).
CATCH cx_sql_exception INTO DATA(exception).
WRITE:/ 'In catch sql exception:' , exception->get_text( ).
ENDTRY.
The code is exactly the same as the first test, except that the exception is changed from CX_ATD_EXCEPTION to CX_SQL_EXCEPTION.
And result for the second test, 囧 …
In order to make this CX_SQL_EXCEPTION caught-able, I have to write the same dirty code as we did in Java example:
Although this time it works, but what is the reason of the different behaviors of these two examples?
The error message and short dump description have already given us a hint.
CX_ATD_EXCEPTION’s super class: CX_NO_CHECK. As its description says, it is not necessary to manually declare it in method signature using RAISING keyword.
And CX_SQL_EXCEPTION’s super class: CX_STATIC_CHECK
As a result now we have another solution:
Create another version of PLEASE_THROW method with RAISING keyword:
Use this new version and now CX_SQL_EXCEPTION could be caught:
WRITE:/ 'Third test' COLOR COL_NEGATIVE.
TRY.
lo_test->please_throw2( lo_exception2 ).
CATCH cx_sql_exception INTO DATA(exception3).
WRITE:/ 'In catch sql exception:' , exception3->get_text( ).
ENDTRY.
Further reading
I have written a series of blogs which compare the language feature among ABAP, JavaScript and Java. You can find a list of them below:
- Lazy Loading, Singleton and Bridge design pattern in JavaScript and in ABAP
- Functional programming – Simulate Curry in ABAP
- Functional Programming – Try Reduce in JavaScript and in ABAP
- Simulate Mockito in ABAP
- A simulation of Java Spring dependency injection annotation @Inject in ABAP
- Singleton bypass – ABAP and Java
- Weak reference in ABAP and Java
- Java byte code and ABAP Load
- How to write a “correct” program rejected by compiler: Exception handling in Java and in ABAP
- An small example to learn Garbage collection in Java and in ABAP
- String Template in ABAP, ES6, Angular and React
- Try to access static private attribute via ABAP RTTI and Java Reflection
- Local class in ABAP, Java and JavaScript
- Integer in ABAP, Java and JavaScript
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
相关文章
- Java实现 LeetCode 830 较大分组的位置(暴力模拟)
- Java实现 LeetCode 140 单词拆分II
- Java实现除去次方数
- java实现第七届蓝桥杯搭积木
- java实现字符串比较
- Java 实现 蓝桥杯 等额本金
- java构造方法的不同
- java复习 --集合类
- [Spring Unit Testing] Spring Unit Testing with a Java Context
- SAP ABAP和Java跨域请求问题的解决方案
- 一段使用Java程序和JCO(Java connector)连接SAP ABAP Netweaver系统的代码
- 使用 Java 11 安装 SAP Commerce Cloud 1905 的一些常见问题
- SAP Java Connector 的配置指南
- 使用 SAP Business Application Studio 搭建 CAP Java 开发环境
- 使用Java代码在SAP Marketing Cloud上创建Contact数据
- Oracle要对Java收费了,SAP基于Java技术栈的那些产品的客户怎么办
- 使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数
- SAP Java GUI integration log
- 如何在Java代码中使用SAP云平台CloudFoundry环境的环境变量
- 如何将 SAP Business Application Studio 里开发的 Java 应用部署到 SAP BTP 上
- 如何在 SAP BTP Java 应用里使用 SAP HANA 数据库
- 如何给运行在 SAP BTP 上的 Java 微服务增添访问控制功能
- 给 SAP BTP 平台上的 Java 应用增添用户登录和认证机制
- 使用 SAP Business Application Studio 搭建 CAP Java 开发环境
- 使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数
- 如何在Java代码中使用SAP云平台CloudFoundry环境的环境变量
- java ava获取当前时间前一周、前一月、前一年的时间
- Java linkedList详细介绍及使用示例
- Java:计算机编程语言Java的简介、安装(编程环境/工具)、学习路线(如何学习Java以及几十项代码编程案例分析)之详细攻略