一起学习Kotlin——Kotlin中的基本数据类型

Kotlin中的基本数据类型

作为Google【官方指定的干儿子】,Kotlin语言今年受到了越来越多的重视。无论是开发Android还是后台程序,这门语言以后一定是大有可为。由于相关的文章很多,那我们不多介绍这门语言是怎么来的。就让我们慢慢来,一点一点的去品味Kotlin。

第一章,一起来看看这门语言的基本数据类型吧。


开始之前,我们需要明确一点:

kotlin是一门【强类型】、【静态类型】、【支持隐式类型】的【显式】类型语言。

PS:
1、强类型:强类型语言的编译器引入了较多的类型检查限制,因此在运行时不会发生未经明确(显示转换)类型转换的类型转换。常见的语言中,Java就是强类型语言,而JavaScript则是弱类型语言。
2、静态类型:根据类型检查在编译时期还是运行时期,我们把语言分为静态类型以及动态类型。静态语言是基于编译器来确保语言类型的安全。
3、显式类型:根据变量名是否需要显式的给出声明,我们可以将语言分为显式类型以及隐式类型。kotlin是显式类型的语言,与此同时又因为有【类型推断】的作用所以可以看做是支持隐式类型。


一、简述

1、var 与 val

kotlin中,var符号表示的事变量,可以多次重复赋值。
而val表示的是“常量”,但这并不是通俗意义上的常量。本质上val也是变量,但一次赋值之后,不能再次修改,只能作为【只读变量】。


2、kotlin中的根类型:Any

kotlin中万物皆对象,所有类型都是引用类型。所有的类都有一个超类:Any。
官方文档是这么说的:

/**
* The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.
*/

这个类只有三个方法:

public open operator fun equals(other: Any?): Boolean
public open fun hashCode(): Int
public open fun toString(): String

如果类声明中,没有指明超类,则默认为Any。
kotlin中的Any映射为java中的java.lang.Object.

特别注意的一点:java中Object只是所有引用类型的超类,而基本类型int、long等不包含在内。而kotlin中,Any是一切的超类。


3、kotlin中的数字类型

3.1、常识介绍

kotlin中常见的数字类型分为以下6种:

方法名 转换类型 补充
Byte 8位 1字节
Short 16位 2字节
Int 32位 4字节
Long 64位 8字节
Float 32位 4字节
Double 64位 8字节

根据名称可以看出基本和java中的相关定义相近。
kotlin支持二进制、十进制、十六进制;

但【不】支持八进制

与此同时,kotlin在数值类型的表示方式上也支持下划线,如:
val Million = 1000_000_000
val tmp = 123_456_789L
val demo = 0xDD_FF_EE

kotlin中的数字类型与java很是相近,但有一点不同:

kotlin没有java语言的隐式变换(如byte->short->int->long 等)。

因此,java中的如下代码,在kotlin中是无法编译的:

short a = 1;
int b = a;

当然,在kotlin中应该这样描述:

val a : Int = 1
val b : Long = a

上述代码同样是无法通过编译的!

因此,遇到类型转换我们就应该考虑一下【显式转换】:
java中,我们一般会这样进行数值类型的显式转换:

int a = 1;
...
Long tmp = (long)a;

而kotlin中,我们可以这样:

val a : Int = 1
val b : a.toLong()

相关的方法汇总如下:

方法名 转换类型
toByte() Byte
toShort() Short
toInt() Int
toLong() Long
toFloat() Float
toDouble() Double
toChar() Char

这里需要注意一点的是:

与java不同,kotlin中Char类型仅仅表示字符,不能再被直接当做数字。 因此,Char类型的变量必须在单引号之间表示:’变量’。(CSDN博客这里显示有误。。。)

一段简单的java代码如下:

char a = 'c';
System.out.println(a+1);

此时打印的结果为【数字】100。
而作为对比,在kotlin中:

val a : Char = 'c'
println(a+1)

上述代码的打印结果为【字符】d

因此我们要明确:Kotlin中 Char类型由于不是直接当数值用,所以最后返回依旧是Char型。


3.2、一些需要注意的点

3.2.1、== 与 ===

kotlin中并没有单纯的数值,在我们定义每一个数值的时候,kotlin编译器都在默默的为我们将定义的数值封装成一个对象,以最大限度的解决空指针异常的问题。因此kotlin中数值的比较除了我们常见的 == 号之外还多了 === 。
当然,根据面向对象的定义也可以快速的了解:

符号名 作用 否定形式
== 【结构相等】比较两个具体的【数值的大小】是否相同 !=
=== 【引用相等】比较两个对象【在内存的存储地址】是否相同 !==

ps:
编译器中,== 等同于equal()方法。

举个栗子来看:

fun main(args: Array){
    val a : Int = 10
    println(a === a) //此处返回的值为true
    val b : Int = a
    println(a === b) //此处返回的值为true,因为赋值操作是内存地址赋值,而内存地址相同,其中的数字值自然相同
    println(a == b) //此处返回的值为true,原因同上

}

【☆☆☆】考虑到装箱问题:数字装箱不保留【同一性】,但保留数值的【相等性】。

    val a: Int = 200
    println(a === a) //此处返回的值为true
    val b :Int ? = a
    println(a === b) //此处返回的值为false,因为这是两个对象,内存地址不相同
    println(a == b) //此处返回的值为true,数值相同

当然还有一个特殊情况,考虑到JVM虚拟机的常量池特性:

val a: Int = 20
    println(a === a) //此处返回的值为true
    val b :Int ? = 20
    println(a === b) //此处返回的值为true
    println(a == b) //此处返回的值为true,数值相同

PS:
【1】JVM虚拟机中维护着有符号整形常量池(-128,127),在这个范围里的数值都会直接使用常量池的内存地址,所以这个范围内的数值装箱后比较内存地址依旧是相等的。(常量池主要用于存放两大类常量:字面量(Literal)和符号引用量(Symbolic References))
【2】kotlin中,?表示这个对象可能为空。因此这一句“val b :Int ? = a”
表示的意思除了普通的数字赋值外,还多了一层含义:如果被赋值对象为空,则开辟内存创建新的对象。

3.2.2、移位操作

在java中,移位操作的表示非常简洁,直接用符号即可表示:

符号名称 作用
<< 左移位操作
*>> 右移位操作(此处*为显示效果)
*>>> 无符号右移位

而在kotlin中,则没有这些简单的符号表示,取而代之的是相应的移位操作方法:

符号名称 作用
shl(bits) 左移位
shr(bits) 右移位
ushr(bits) 无符号右移位
and(bits) 与操作
or(bits) 或操作
xor(bits) 异或操作
inv() 反向操作
3.2.3、运算符 + 的重载

先来看一段代码:

val a = 10L + 1

很明显,上述代码中,+ 左右两个数分别为Long类型与Int类型。
那么问题来了,我们前面说过,kotlin中并不支持数字类型的隐式转换,而且上面表达式中的数字1并没有显示拓宽为Long类型,为何却准确无误呢???
答案很简答,那就是kotlin中对于符号“+”的重载。
一起学习Kotlin——Kotlin中的基本数据类型_第1张图片

看一看到,源码中有很多重载的方法。
当我们执行:val a = 10L + 1
实质上是:
val a = 10L.plus(1)

值得注意的一点是:XX.plus()方法中传入的形参只能为数值类型!


4、kotlin中的字符类型

kotlin中的基本字符为Char类型,相关的知识点我们已经在前文讨论过。


5、kotlin中的布尔类型

布尔用 Boolean 类型表示,它有两个值:true 和 false。
若需要可空引用布尔会被装箱。


6、kotlin中的字符串类型

kotlin中字符串是String类型。
与java类似,kotlin中的String同样是由final修饰的,即不可被继承。我们一起来看一些新的特性。

6.1、支持多行字符串

val string = """
            line 1
            line 2
            lin3 4
            """

注意以上代码的打印结果是存在前置的空格号的:
一起学习Kotlin——Kotlin中的基本数据类型_第2张图片

我们可以借助与 trimMargin() 发放做到去除掉每行的前置空格。

val string = """
            |line 1
            |line 2
            |lin3 4
            """.trimMargin("|")

这里有一点需要注意:trimMargin()方法需要传入一个String类型的参数作为删除前置空格并进行每行分割的标志Flag,我们在这里选用了”|”。

6.2、支持字符串模板

在kotlin中,字符串可以包含字符串模板用来表示前面用的到的一段代码。kotlin中规定,所有的字符串模板必须以美元符号”$”开头。

 val a = "temp"
 val q = "$a.length():"
 println(q+a.length)

打印结果为:
打印结果2

原生字符串和转义字符串内部都支持模板。

6.3、索引运算符s[i]

当我们需要对一个字符串的某一位取值时,java中会用到:

"abc".charAt(i);

而在kotlin中,我们可以简单的用索引运算符即可:

val s = "abc"
s[0]//结果为a

6.4、for循环迭代字符串

    for (s in "12345"){println(s)}

打印结果:
一起学习Kotlin——Kotlin中的基本数据类型_第3张图片


7、kotlin中的数组类型

7.1、生成数组

kotlin中的数组不是new出来的而是用了别的表示方法:
【1】fun_1

    val a = arrayOf(1,2,3) //1,2,3

【2】fun_2 工厂函数

    val b = Array(3, { i -> (i * 2) })//0,2,4

7.2、数组的多类型表示

kotlin中的数组支持多类型:

    val arr = arrayOf(1,2,true,"abc")
    for(c in arr){println(c)}

上述代码的打印结果为:
打印结果12
注意:在这里kotlin编译器自动将数组升级为java.lang.Object类型了。
打印结果123

7.3、新建空数组

除此之外在新建空数组时,我们必须显示地知名数组元素的类型:

    val b = arrayOfNulls(10)//错误
    val b = arrayOfNulls(10)//正确

7.4、数组转换

注意:kotlin中数组不是形变的,即我们不能将Array赋值给Array。


你可能感兴趣的:(Android开发,JAVA/Kotlin语言,Kotlin学习笔记)