Android学习Kotlin之二、Null安全 -字符串操作- 类型转换

Null安全

在Java中我们司空见惯的空指针异常NullPointerException,带给了我们很多麻烦。Kotlin作为更强大的语言,势必会基于以往的语言设计经验对其进行改良。Kotlin更多地把运行时可能会出现的null问题,以编译时错误的方式,提前在编译期强迫我们重视起来,而不是等到运行时报错,防范于未然,提高了我们程序的健壮性。

Kotlin

其它Kotlin文章
Android学习Kotlin之一、常量-条件-函数-高阶函数
Android学习Kotlin之二、Null安全 -字符串操作- 类型转换
Android学习Kotlin之三、标准库函数-集合List-Set-Map
Android学习Kotlin之四、定义类-初始化-继承
Android学习Kotlin之五、对象-接口-抽象类
Android学习Kotlin之六、泛型-扩展函数

本编文章会讲到的知识点

  • Null安全
    • 非空类型
    • 可空类型
    • ?空安全操作符
    • let操作符
    • !!操作符
    • if判断
    • ?:空合并操作符
    • filterNotNull()可空类型的集合
    • 异常处理
    • 先决条件函数
  • 字符串操作
    • substring
    • split
    • replace
    • 字符串比较
    • forEach
  • 类型检测
    • is运算符
    • as运算符
  • 类型转换
    • 类型自动转换
    • 安全转换
    • double转int
    • double类型格式化

Null安全

非空类型

对于null值问题,Kotlin默认变量不可为null值,这样一来运行时崩溃从根源上得到了解决。而java中可以设置变量为null值。

    var nullNmae = "打死你个Null"//默认情况下不可以为空
    nullNmae = null//报错
设置Null报错

可空类型

为了避免空指针异常,kotlin的做法是不让我们给非空类型变量赋null值,但null在Kotlin中依然存在。在类型后面加上?表示此变量可为null。

    var mailName: String?//可以设置为空
    mailName = null
    println(mailName)//打印 null

?空安全操作符

?操作符使用修饰申明在成员变量的类型后面,该变量如果为null时,不会执行该变量后面的逻辑,也不会抛出空指针异常,俗称空安全。如果不为null,会正常执行该变量后面的内容。

    var womanName: String? = "aaa"
//    println(womanName.length)//报错womanName可能为空,报空安全
    println(womanName?.length)//打印 3

let操作符

当需要定义一个变量在一个特定的作用域时,可以考虑使用 let 函数。当然,更多的是用于避免 Null 判断。在 let 函数内部,用 it 指代调用 let 函数的对象。

    val listWithNulls: List<String?> = listOf("Kotlin", null)
    for (item in listWithNulls) {
        item?.let { println(it) } // 输出 Kotlin 并忽略 null
    }

!!操作符

!!加载变量后面,如果变量为null时会抛出空指针异常,像java语法一样空指针不安全;如果不为null,继续执行后面的代码。

    var mName:String? = "xiaoming"
    println(mName!!.length)

if判断

和java语法一样,使用If判断变量活对象是否为null

    var d:String? = "dddddd"
    println(if(d!=null) d.length else -1)// 打印 6

?:空合并操作符

如果 ?: 左侧表达式非空,elvis 操作符就返回其左侧表达式,否则返回右侧表达式(仅当左侧为空时,才会对右侧表达式求值。可以代替if else

    var b:String? = "abc"
    b = null
    val l = b?.length ?: -1
    println(l)//打印 -1

filterNotNull()可空类型的集合

如果你有一个可空类型元素的集合,并且想要过滤非空元素,你可以使用 filterNotNull 来实现

    val nullableList: List<Int?> = listOf(1, 2, null, 4)
    val intList: List<Int> = nullableList.filterNotNull()
    println(intList)// 打印 “[1, 2, 4]”

异常处理

Kotlin 的异常和 Java 的一样, try…catch…finally代码块处理异常,唯一一点不同是:Kotlin 的异常都是 Unchecked exceptions。

  • 抓取异常
var number: Int? = null
    try {
        number!!.plus(1)// 报错打印 java.lang.NullPointerException
    } catch (e: Exception) {
        println(e)
    }
  • 自定义异常
 // 检查抛出异常
    fun checkNull(number:Int?){
        number ?: throw MyException()
    }

    var number: Int? = null
    try {
        checkNull(number)//抛出异常com.example.kotlinjetpack.kotlin.MyException: 我是自定义异常
        number!!.plus(1)
    } catch (e: Exception) {
        println(e)
    }
// 自定义异常类
class MyException() :IllegalArgumentException("我是自定义异常")

先决条件函数

Kotlin标准库提供了一些便利函数,使用这些内置函数,你可以抛出带自定义信息的异常,这些便利函数叫做先决条件函数,你可以用它定义先决条件,条件必须满足,目标代码才能执行。

先决条件函数
   // 检查抛出异常
    try {
        checkNotNull(number,{"checkNotNull is null"})//java.lang.IllegalStateException: checkNotNull is null
        number!!.plus(1)
    } catch (e: Exception) {
        println(e)
    }

字符串操作

substring

字符串截取,substring函数包前不包后,支持IntRange类型 (上篇文章讲过此用法),until创建的范围不包括上限值。

    val str = "Hello My Friend"
    val index = str.indexOf('o')//4
    println(str.substring(0,index))//Hell
    println(str.substring(0 until index))//Hell
    println(str.substring(0..index))//Hello

split

split函数返回的是List集合数据,List集合又支持解构语法特性, 它允许你在一个表达式里给多个变量赋值,解构常用来简化变量的赋值。

    val str2 = "千玺,王源,俊凯"
    val list = str2.split(",")
    println(list)//打印 [千玺, 王源, 俊凯]
    var (name1,name2,name3)= str2.split(",")//结构分析,和ES6语法很像
    println("$name1 $name2 $name3")//打印 千玺 王源 俊凯
    var (name1,name2,name3,name4)= str2.split(",") //因为数组中只有三个元素,如果解构赋值写了四个会报错下标越界IndexOutOfBoundsException

replace

Kotlin中的字符串替换方法,String.replace(oldValue: String, newValue: String, ignoreCase: Boolean = false): String
参数: ignoreCase = true区分大小写默认为false

    val str3 = "Hello My Friend haha"
    println(str3.replace('h', 'G'))//Hello My Friend GaGa
    println(str3.replace('h', 'G', ignoreCase = true))//Gello My Friend GaGa
    // 第一个参数是正则表达式,决定哪些要替换哪些字符
    // 第二个参数是匿名函数,处理要替换的字符
    var s = str3.replace(Regex("[Hyda]")){
        when(it.value){
            "H"->"1"
            "y"->"2"
            "a"->"3"
            else->"4"
        }
    }
    println(s)//1ello M2 Frien4 h3h3

字符串比较

在Kotlin中,用==检查两个字符串中的字符是否匹配,用===检查两个变量是否指向内存堆上同- -对象,而在Java中= =做引用比较,做结构比较时用equals方法。String字符串变量是不可变的,如果修改字符串会在内存中重新创建一个内存来赋值给这个变量。

    var s1 = "Hello"
    var s2 = "hello".capitalize()//修改了s2值
    println("$s1 $s2")//Hello Hello
    println(s1 == s2)//true
    println(s1 === s2)//false

forEach

遍历字符串

    "Hello My Friend".forEach {
        println(it)//H e l l o  M y  F r i e n d
    }

类型检测

is运算符

is运算符相当于java中的 instanceof,来判断是哪种类型。

    println("name" is String)// true
    println("name" !is String) // fasle
    println(666 is Number) // true
    println(666 !is Number) // false

as运算符

as运算符用于执行引用类型的显示类型转换,如果类型与指定类型相符,就会转换成功,如果类型不兼容,使用as?就会返回null。

    open class Ani {
    }

    class Dog : Ani() {
    }
    val ani = Ani()
    val dog = Dog()
    println((dog as Ani))
    var a: Ani? = dog as? Ani
    println(a)

类型转换

类型自动转换

在java中判断出某个变量是什么类型后,想要使用其属性和方法时需要先强转其类型后才能调用其属性活方法。在kotlin中知道变量是什么类型后,无需强转其类型,直接可以调用其属性或方法。

    var n = "abc"
    println(n.length)

安全转换

Kotlin提供了toDoubleOrNull和tolntOrNull这样的安全转换函数,如果数值不能正确转换,与其触发异常不如干脆返回nul|值。

    println("100".toInt())
    println("100.66".toDouble())
//    println("6.66".toInt()) 报错 java.lang.NumberFormatException: For input string: "6.66"
    println("6.66".toIntOrNull())// null

double转int

    println(6.6666.toInt())// 精度损失 6
    println(6.6666.roundToInt())// 四舍五入 7

double类型格式化

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

推荐阅读更多精彩内容