Kotlin 学习教程之类型系统和智能类型转换(二)

说在前面

从上一篇我们了解了 kotlin 这门语言,以及通过 IntelliJ IDEA 和 AndroidStudio 开发工具创建了 kotlin 项目并运行了 “hello world” 程序,在这一篇,我们将来学习 kotlin的数据类型系统,以及各种类型之间的转换。

1. Java 类型系统
image

由上图可知:在 Java 中,类型系统由8种基本类型,6种引用类型以及一种空特殊的空引用类型。

  • 基本类型:byte,char,short,long,float,double,int,boolean

  • 引用类型:

    • 类:class

    • 接口:interface

    • 数组:array

    • 参数化类型:泛型

    • 注解:Annotation

    • 枚举:enumeration

  • 空引用:null

基本数据类型和引用数据类型在创建的时候,内存的存储方式区别:

  • 基本数据类型:在被创建时,在栈上给其划分一块内存,将数值 直接存储在栈上(性能高);

  • 引用数据类型:在被创建时,首先在栈上给其引用(句柄)分配 一块内存,而对象的具体信息存储在堆内存上,然后由栈上面 的引用指向堆中对象的地址。

2.kotlin 类型系统

在 kotlin 中,将类型系统根据数据是否可空分为了可空类型和不可空类型。可空类型能够在编译程序的时候进行类型检查,以提前发现并解决问题,大大的降低了出现空指针的情况。

2.1 不可空类型

kotlin 中不可空的数字类型对应了 Java 中的原始类型,但是写法却 不一样:

  • Kotlin中的数字类型与 Java 原始的数字类型
Snipaste_2020-02-17_10-31-55.png
// 声明Int 型
val age:Int=20
//声明Long 型
val along:Long=12368172397127391
//声明 Float 型
val aFloat:Float=2.0F
//声明 double 型
val aDouble:Double=3.0
//声明 Short 型
val aShort:Short=127
// 声明Byte 型
val maxByte: Byte = Byte.MAX_VALUE
//声明Boolean
val aBoolean: Boolean = true

以上都是不可空的数字类型,在声明变量的时候都给它们赋了值,但是如果我们不给它赋值或者赋值为空,则编译器会显示错误,提醒我们必须要初始化该数字类型的值。

Snipaste_2020-02-17_10-31-55.png
Snipaste_2020-02-17_10-31-55.png
  • Kotlin中可空数字类型与 Java 中装箱数字类型


    Snipaste_2020-02-17_10-31-55.png

    Snipaste_2020-02-17_10-31-55.png
2.2 可空类型

在Java 开发中,经常会遇到空指针的问题,那么能不能在编译的时候提前发现错误并进行代码修复呢?kotlin中出现了可空类型以解决这个痛点。我们以如下输出字符串str的长度代码为例:

  • kotlin中:
val str:String? ="hello world"
fun getLength():Int{
    return str?.length?:0
}
fun main(args: Array<String>) {
   println("str字符串的长度为:${getLength()}")
}
  • Java代码:
public class helloword {
    static String str = "hello world";
    public static void main(String[] args) {
        System.out.print("str 字符串的长度为:" + getLength());

    }

    public static int getLength() {
        if (str != null) {
            return str.length();
        } else {
            return 0;
        }
    }
}

在kotlin 代码中 str?.length?:0 就是 kotlin中常用的 Elvis表达式,它的意思是如果str为不空,那就返回 str.length的值,否则返回0。同样的需求,不一样量的代码,kotlin是不是显得更加精简全面呢?显然是的。

2.3 安全操作符

(1)安全调用符:"?."

val str:String? ="hello world"
fun main(args: Array<String>) {
   // 方式一:
    if (str != null) {
        println(str.length)
    }
    // 方式二:
    println(str?.length)
}

我们知道,在程序中,不能使用可空的对象直接调用其属性或者方法,否则会直接报错,在Java 中也会出现空指针异常。在以上代码中,在保证程序的正常执行的情况下,方式一和方式二需求一样,但是方式二使用了安全调用符 ?.是得代码更加的简洁。程序只有在str不为空的情况下才会执行 str.length的方法。

(2)Elvis运算符“?:”

在前面例子中 str?.length?:0 就使用了Elvis运算符“?:”,同理只有str不为空的情况下才会执行 str.length的方法

(3)非空断言“!!”

Kotlin中提供了断言操作符“!!”,它表示已经确定该可空对象不为空且直接调用其属性或方法。该操作符需要谨慎使用,因为一旦遇到了该对象为空的时候,则会导致空指针异常。代码及结果如下:

Snipaste_2020-02-17_10-31-55.png
3.类型检测和智能类型转换
3.1 is 和 !is 运算符

is运算符是用来检测对象A是否与特定的类型X兼容(此对象A是X类型或者派生于X类型)

Snipaste_2020-02-17_10-31-55.png
3.2 Java 和kotlin中的类型转换

例子:

  • 现有一个子类,一个父类,子类和父类各自拥有一个方法

  • 需要实现父类调用子类的方法 以及子类调用父类的方法打印输出"hello kotlin"

(1)Java 代码实现

Snipaste_2020-02-17_10-31-55.png

(2)kotlin代码实现


Snipaste_2020-02-17_10-31-55.png

对比以上代码可知:Java 中父类在调用子类方法获取 “kotlin”字符串的时候,编译器中进行了强制类型转换,而kotlin 代码中,父类直接调用了子类的getKotlin(),并没有进行强制类型转换,这是因为编译器已经知道它该父类本来就是子类的实例,无需再进行强转。

3.3 kotlin中智能类型转换

在kotlin中,使用 as 进行引用类型的显式类型转换类型转换,但如果类型转换失败会出现类型转换失败的异常,使用 as?运算符进行智能类型转换,当转换失败的时候直接返回null,代码如下:

fun main(args: Array<String>) {
    val parent: Parent = Parent()
    val child: Child? =parent as? Child
    println(child?.getKotlin())

}
open class Parent{
    fun getHello():String{
        return "hello"
    }
}
class Child : Parent() {
    fun getKotlin(): String {
        return "kotlin"
    }
}

以上代码,父类转换为子类并调用其方法,会出现类型转换失败的异常,但是使用了as?运算符,会直接输出null而避免了异常。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容