3.1 类型系统
定型(typing,又称类型指派)的过程就是赋予一组比特以具体的意义。类型通常和存储器中的数值或对象(如变量)相联系。因为在计算机中,任何数值都是由一组简单的比特位组成的,硬件无法区分存储器地址、脚本、字符、整数及浮点数。类型可以告知程序和程序设计者,应该怎么对待那些比特位。
3.1.1 类型系统的作用
使用类型系统,编译器可以检查无意义的、无效的、类型不匹配等错误代码。这也正是强类型语言能够提供更多的代码安全性保障的原因之一。
另外,静态类型检查还可以提供有用的信息给编译器。与动态类型语言相比,由于有了类型的显式声明,静态类型的语言更加易读好懂。
有了类型,我们还可以更好地做抽象化、模块化的工作。这使得我们可以在较高抽象层次思考并解决问题。例如,Java中的字符数组char[]s={'a','b','c'}和字符串类型String str="abc"就是最简单、最典型的抽象封装实例。下面分别举例说明。
字符数组代码示例如下:
字符串代码示例如下:
3.1.2 Java类型系统
Java类型系统可以简单用下面的图3-1来表示。
图3-1 Java类型系统
关于Java中的null,有很多比较“坑”的地方。例如:
基本数据类型与引用数据类型在创建时,内存存储方式区别如下:
- 基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上(性能高);
- 引用数据类型在被创建时,首先在栈上给其引用(句柄)分配一块内存,而对象的具体信息存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。
3.1.3 Kotlin的类型系统
Java是一个近乎“纯洁”的面向对象编程语言,但是为了编程方便还是引入了基本数据类型。为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类型就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。Java为每个原始类型提供了相应的包装类型。
- 原始类型:boolean,char,byte,short,int,long,float,double。
- 相应的包装类型:Boolean, Character, Byte, Short, Integer, Long, Float, Double。
Kotlin中去掉了原始类型,只有包装类型,编译器在编译代码的时候,会自动优化性能,把对应的包装类型拆箱为原始类型。
Kotlin系统类型分为可空类型和不可空类型。Kotlin中引入了可空类型,把有可能为null的值单独用可空类型来表示。这样就在可空引用与不可空引用之间划分出一条明确的、显式的“界线”。
Kotlin类型层次结构如图3-2所示。
图3-2 Kotlin类型层次结构
通过这样显式地使用可空类型,并在编译期作类型检查,大大降低了出现空指针异常的概率。
对于Kotlin中的数字类型而言,不可空类型与Java中原始的数字类型对应,如表3-1所示。
Kotlin中对应的可空数字类型就相当于Java中的装箱数字类型,如表3-2所示。
表3-1 Kotlin中的数字类型与Java中原始的数字类型
表3-2 Kotlin中的可空数字类型与Java中的装箱数字类型
在Java中,从基本数字类型到引用数字类型的转换过程就是典型的装箱操作,例如int转为Integer。倒过来,从Integer转为int就是拆箱操作。同理,在Kotlin中非空数字类型Int到可空数字类型Int?需要进行装箱操作。同时,非空的Int类型会被编译器自动拆箱成基本数据类型int,存储的时候也会存到栈空间。例如下面的代码,当为Int类型的时候,a===b返回的是true;而当为Int?的时候,a===b返回的是false。
上面返回的都是true,因为a、b它们都是以原始类型存储的,类似于Java中的基本数字类型。
可以看出,当a、b都为可空类型时,a与b的引用是不等的。“等于”号的简单说明如表3-3所示。
表3-3 Kotlin中的“等于”号说明
另外,Java中的数组也是一个较为特殊的类型。这个类型是T[],这个方括号让我们觉得不太“优雅”。Kotlin中摒弃了这个数组类型声明的语法。Kotlin简单直接地使用Array类型代表数组类型。这个Array中定义了get、set算子函数,同时有一个size属性代表数组的长度,还有一个返回数组元素的迭代子Iterator的函数iterator()。完整的定义如下:
其中,构造函数我们可以这么用:
在编程过程中常用的是boolean[]、char[]、byte[]、short[]、int[]、long[]、float[]、double[];Kotlin直接使用了8个新的类型来对应这样的编程场景:
BooleanArray ByteArray CharArray DoubleArray FloatArray IntArray LongArray ShortArray