6.变量声明与基本类型(Primitive Type)

2020-03-09 11:43:51 浏览数 (1)

本文将会介绍 Java 的基本类型和 Kotlin 的区别。我们知道,Java 的基本类型是 boolean, char, short, int, long, float, double。这些基本类型不是对象,只可以进行基本的数学逻辑运算。Java 虽然打着“一切皆对象”的口号,但在基本类型还是留了一手。他们是特别的存在。

至于为什么要保留基本类型,真相只有一个:性能。大部分基本类型操作是一条指令就可以完成的,而对象方法调用则需要很多条指令才能完成;另外占用内存相比对象,也小很多。可以说 Java 诞生初期,在概念统一和性能的权衡下,把天平偏向了性能。这也很合理:90 年代时候的硬件速度还非常慢。且 Java 最初是为嵌入式设备而设计的,后面才把目标改为互联网。

现在市面上大部分的银行卡,里面装的是 Java 虚拟机,开发者通过编写受限的 Java 代码来实现一个叫 Applet 的应用单元,并装载到银行卡中。银行卡被插入后,机器会通过针脚或 NFC 和银行卡进行通讯。这种技术叫 Java Card 技术。 所谓受限的 Java 代码,没有 String,没有 JDK,甚至大部分连 int 都不支持。只能用 byte 和 short。因为芯片是 16 位的。 我上一份工作,在银行卡上实现了三种数字货币的交易协议。。

我们不妨把 Java 的面向对象称为不完全面向对象。那么是否有“真·面向对象”语言?有的。如 Smalltalk,Python,Kotlin 就是。在他们的编程环境里,没有基本类型,是真正的“一切皆对象”。这样带来的好处是概念的统一。“基本类型”这样的概念不再被需要,不再需要特别的处理它,所有声明出来的变量都具有同样的行为,不再需要区分引用类型和值类型。说到引用类型和值类型,大家在初学 Java 的时候应该都花了不少功夫去理解吧?

当然了,Java 也有基本类型对应的对象封装。如 int 对应 Integer,float 对应 Float,并且 jdk1.5 之后提供了自动装箱拆箱的编译器特性。但因为写起来比基本类型麻烦,且考虑性能问题,导致如果不是限定场景,大家都不会主动用它们。

而 Kotlin 为了提供完全面向对象的特性,摒弃了基本类型。但 Kotlin 没有直接使用 Java 的 java.lang.Integer,java.lang.Float 装箱类,而是另起山头,创造了 kotlin.Int,kotlin.Float 等类,因为别人写的代码都是 shit,因为 Java 的装箱类是集成在 JDK 的,无法随着 Kotlin 版本更新而更新。且在 Kotlin 中,数值类还有拥有额外的编译特性:

前面说到 Java 因为性能问题,保留了基本类型。那么 Kotlin 选择了完全面向对象,那理应要承受一定的性能损失。但其实 Kotlin 在编译成 jvm 字节码的时候,大部分的 Int 都会编译回 int,小部分会被编译成 Integer。这个小部分,典型的情况就是你声明一个变量为可空类型时,即声明为 Int?,这个时候无法使用 jvm 的基本类型结构。

而我们观察 kotlin.Int 时,可以看到除了数学运算的运算符重载方法,和强转的方法(toFloat,toLong 等)外,就没有其他方法了,而这些方法都可以直接对应基本类型运算的操作。kotlin.Int 声明为这样一个简洁的数值封装类,让转换为 jvm 字节码的基本类型铺平道路。

所以使用 kotlin 的数值类型时,绝大部分场景下,不会有额外的性能开销。

版权所有,转载请注明出处: https://cloud.tencent.com/developer/article/1595756

0 人点赞