ABAP,Java和JavaScript的整型数据类型比较
When I first begin to program with ABAP I get confused with different kinds of integer type available for ABAP developers: i, int1, int2, int4, and int8.
According to ABAP help, predefined data types consists of two types:
(1) predefined ABAP types: b, c, d, decfloat16, decfloat34, f, i, int8, n, p, s, string, t, x, and xstring. (2) predefined dictionary types: INT1, INT2, INT4, INT8,DEC,DF16_DEC,DF16_RAW,DF34_DEC,DF34_RAW and FLTP.
How to understand the difference between these two types
The predefined dictionary types could be used to define other dictionary datatype:
However it is not possible to use a predefined ABAP type:
All these five types could be directly used in ABAP code to define the type of a variable, and i and int4 have the same technical type, see example below:
Value range of each type
The range of each types could be calculated via formula:
where n = 2, 4, 8. For n = 1, since int1 is unsigned char, all the whole 8 bit of 1 byte could be used to represent the numeric value, so the range should then be:
The constant range of int4 and int8 are defined in class CL_ABAP_MATH:
while int1 and int2 are defined in another class CL_ABAP_EXCEPTIONAL_VALUES:
Integer and RTTI
Test via the following code:
DATA: lv1 TYPE i VALUE 1,
lv2 TYPE int1 VALUE 1,
lv3 TYPE int2 VALUE 1,
lv4 TYPE int4 VALUE 1,
lv5 TYPE int8 VALUE 1.
DATA: lv1_copy TYPE i VALUE 2,
lv2_copy TYPE int1 VALUE 2.
DATA(lo1) = cl_abap_typedescr=>describe_by_data( lv1 ).
DATA(lo2) = cl_abap_typedescr=>describe_by_data( lv2 ).
DATA(lo3) = cl_abap_typedescr=>describe_by_data( lv3 ).
DATA(lo4) = cl_abap_typedescr=>describe_by_data( lv4 ).
DATA(lo5) = cl_abap_typedescr=>describe_by_data( lv5 ).
DATA(lo1_copy) = cl_abap_typedescr=>describe_by_data( lv1_copy ).
DATA(lo2_copy) = cl_abap_typedescr=>describe_by_data( lv2_copy ).
Result shows that lo1 and lo1_copy point to the same element descriptor reference since they are both performed on variable with the same type i.
The same holds true for lo2 and lo2_type ( int1 ).
Although i and int4 have the same technical type, however since their absolute type are different, so different descriptor reference are returned ( lo1 and lo4 ).
Value comparison and reference comparison
It is not difficult to forecast the result of test below:
DATA: lv_i1 TYPE i VALUE 1,
lv_i2 TYPE int4 VALUE 1,
lv_i3 TYPE int8 VALUE 1,
lv_i4 TYPE int4 VALUE 1.
WRITE: / 'l1 = l2?' , boolc( lv_i1 EQ lv_i2 ).
WRITE: / 'l1 = l3?' , boolc( lv_i1 EQ lv_i3 ).
WRITE: / 'l2 = l3?' , boolc( lv_i2 EQ lv_i3 ).
DATA: lo_i1 TYPE REF TO i,
lo_i2 TYPE REF TO int1,
lo_i3 TYPE REF TO int2.
lo_i1 = NEW #( 1 ).
lo_i2 = NEW #( 1 ).
lo_i3 = NEW #( 1 ).
WRITE: / 'o1 = o2?' , boolc( lo_i1 EQ lo_i2 ).
WRITE: / 'o1 = o3?' , boolc( lo_i1 EQ lo_i3 ).
WRITE: / 'o2 = o3?' , boolc( lo_i2 EQ lo_i3 ).
WRITE: / 'o1->* = o2->* ?' , boolc( lo_i1->* EQ lo_i2->* ).
WRITE: / 'o1->* = o3->* ?' , boolc( lo_i1->* EQ lo_i3->* ).
WRITE: / 'o2->* = o3->* ?' , boolc( lo_i2->* EQ lo_i3->* ).
Integer in Java
Before we start the explore in Java, see the following crazy code:
Yes, 2 + 2 = 5 in Java?! Before I unveil the source code of method doSomethingMagic, let’s first see another example which is easier to understand.
I perform the accumulation from 0 to 10000 and repeat it for 10000 times. I did this operation twice with different approaches: calc1 and calc2. The logic inside the two methods are exactly the same except that different types are used for iterator variable i and variable to store add result in each loop.
public class IntegerCompare {
private static long start;
private static void start(){
start = System.currentTimeMillis();
}
private static long end(){
return System.currentTimeMillis() - start;
}
private static final int NUM = 10000;
private static int calc1(){
Integer result = 0;
for( Integer i = 0; i < NUM; i++){
result += i;
}
return result;
}
private static int calc2(){
int result = 0;
for( int i = 0; i < NUM; i++){
result += i;
}
return result;
}
public static void main(String[] args) {
System.out.println("Calc1: " + calc1());
System.out.println("Calc2: " + calc2());
start();
for( int i = 0; i < NUM; i++){
calc1();
}
System.out.println("Calc1 time: " + end());
start();
for( int i = 0; i < NUM; i++){
calc2();
}
System.out.println("Calc2 time: " + end());
}
}
The printed time shows that the second approach has much better performance than the first.
Decompile the .class file and we can know the reason of this performance difference. In the first solution, there are lots of object instance method call intValue and static method call Integer.valueOf which are much expensive compared with operations against primitive type int.
There is so called Autoboxing and unboxing in Java Specification. Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example when you write the following code:
Integer a = 10;
Decompile the .class file and we find that Java compiler translate the code into:
Integer a = Integer.valueOf(10);
It is the very huge amount of Autoboxing operations in the first approach which leads to a poor performance compared with the second solution.
Why 2 + 2 = 5?
Now it’s time to go back to the mysterious method doSomethingMagic in the example. First check how Integer.valueOf is implemented in JDK. Nothing special there, ABAPer should be very familiar with such style: first check whether the primitive value to be boxed has already corresponding buffered instance in IntegerCache.cache ( just consider it as an internal table in ABAP ). If buffer hits, directly return the entry, otherwise instantiate a new boxed instance. By default the buffer logic only cover the range -128 ~ 127.
Now let’s see the source code of doSomethingMagic, where one entry in Integer buffer maintained by IntegerCache.cache is modified by reflection.
The 132nd entry, which originally represents for primitive value 4, is now overwritten by 133rd entry ( primitive value 5 ).
And 2 + 2 is actually converted by Compiler as Integer.valueOf(4) in compilation time:
So finally “5” is returned as the result of Integer.valueOf(4):
Last but not the least, in ABAP we have similar utility method as Integer.valueOf in Java which converts the input Char like value into a real INT8 value.
Integer in JavaScript
Since now we already the knowledge of Autoboxing and unboxing, it is pretty easy to understand the logic in JavaScript as well. In Java it is not possible to perform any method call on an variable with primitive type:
However it is possible in JavaScript. Check the examples below, where the autoboxing occurs – an new Number object is created under the hood.
(1).toString() equals to code below:
var a = new Number(1);
a.toString();
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
- Fibonacci Sequence in ES5, ES6 and ABAP
- 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
- Covariance in Java and simulation in ABAP
- Various Proxy Design Pattern implementation variants in Java and ABAP
- Tag(Marker) Interface in ABAP and Java
- Bitwise operation ( OR, AND, XOR ) on ABAP Integer
- ABAP ICF handler and Java Servlet
- Mysql备份系列(3)--innobackupex备份mysql大数据(全量+增量)操作记录
- 微信小程序开发:设置消息推送
- Mysql备份系列(1)--备份方案总结性梳理
- ASP.NET中常用的优化性能的方法(转贴,Icyer收集整理)
- 顶象全场景IoT安全方案解决物联网两大难题
- 诡异的【session丢失】和【<img src="">标签】
- TensorFlow核心使用要点
- “搜一搜”直达生活服务 微信连接移动消费新场景
- Linux服务器安全登录设置记录
- Linux系统下的ssh使用(依据个人经验总结)
- 从MapX到MapXtreme2004[4]-标注AutoLabel
- Linux下锁定账号,禁止登录系统的设置总结
- 深度解析 TypeConverter & TypeConverterAttribute (一)
- 从MapX到MapXtreme2004[7]-对Table、Feature等的理解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- CentOS7下安装Elasticsearch-7.3.2和Elasticsearch-head
- spring boot oauth2 取消认证
- 日志级别记录规范
- 搭建K8S集群之node节点部署
- ent orm笔记2---schema使用(上)
- ent orm笔记4---Code Generation
- 什么?明明是2020年12月30日显示2021年12月30日?
- JDK1.8HashMap源码学习-数据结构
- JDK1.8HashMap源码学习-初始化
- JDK1.8HashMap源码学习-put操作以及扩容(一)
- 数据科学家极力推荐核心计算工具-Numpy的前世今生(上)
- 什么是运维眼中可部署的软件架构
- 2020-09-03:裸写算法:回形矩阵遍历。
- Java并发编程系列34 | 深入理解线程池(下)
- MySQL 8.0新特性 — 密码管理