一、Kotlin的可空性
null 在java中我们司空见惯的空指针异常NullPointerException,带给了我们很多麻烦。
Kotlin作为更强大的语言,势必会基于以往的语言设计经验对其进行改良。Kotlin更多
地把运行时可能会出现的null问题,以编译时错误的方式,提前在编译期强迫我们重视起来,
而不是等到运行时报错,防范于未然,提高了我们的程序的健壮性。
二、Kotlin中的安全调用操作符,非空断言操作符,空合并操作符的详解,代码中已经给出详细注释
fun main() { /** * 可空性:? * 对于null值问题,Kotlin反其道而行之,除非另有规定,变量不可为null值,这样一来, * 运行时崩溃问题从根源上得到解决。 * * Kotlin的null类型: * 为了避免NullPointerException,Kotlin的做法是不让我们给非空类型变量赋null值, * 但null在Kotlin中依然存在。 */ var str: String? = "butterfly" str = null println(str) /** * null安全: * 1.Kotlin区分可空类型和非可空类型,所以,你要一个可空类型变量运行,而它又可能 * 不存在,对于这种潜在危险,编译器时刻警惕着。为了应对这种风险,Kotlin不允许你在 * 可空类型值上调用函数,除非你主动接收安全管理。 */ /** * 选项一: 安全调用操作符:?. * 这次Kotlin不报错了,编译器看到有安全调用操作符,所以它知道如何检查null值。如果 * 遇到null值,它就跳过函数调用,而不是返回null。 */ println(str?.capitalize()) str = "butterfly" str = str?.let { //非空白的字符串 if (it.isNotBlank()) { it.capitalize() } else { "butterfly test" } } println(str) /** * 选项二:使用非空断言操作符: * 1.!!.又称感叹号操作符,当变量值为null时,会抛出KotlinNullPointerException */ // str = null // println(str!!.capitalize()) /** * 选项三:使用if判断null值情况 * 我们可以使用if判断,但是相比之下安全调用操作符用起来更灵活,代码也更简洁,我们 * 可以用安全操作符进行多个函数的链式调用。 */ if (str != null) { str.capitalize() } else { println("str 是空的") } str = str?.capitalize()?.plus(" is great.") println(str) /** * 使用空合并操作符 * ?:操作符的意思是,如果左边的求值结果为null,就使用右边的结果值 */ str = null println(str ?: "str is null") /** * 空合并操作符也可以和let函数一起使用来代替if/else语句 */ str = null str = str?.let { it.capitalize() } ?: "butterfly" println(str) }
输出结果如下:
null null Butterfly Butterfly is great. str is null butterfly
三、异常处理和自定义异常,先决条件函数
fun main() { var number: Int? = null try { checkOperation(number) number!!.plus(1) } catch (e: Exception) { println(e) } } fun checkOperation(number: Int?) { // number ?: throw UnSkilledException() /** * 先决条件函数 * Kotlin标准库提供了一些便利函数,使用这些内置函数,你可以抛出带自定义 * 信息的异常,这些便利函数叫做先决条件函数,你可以用它定义先决条件,条件必须满足 * 目标代码才能执行。 */ checkNotNull(number) { "Something is not good" } } /** * 自定义异常 * IllegalArgumentException 有一个是java.lang包下的 * 另外一个是kotlin下面的,kotlin下面的其实只是一个别名等于java.lang包下的 * @SinceKotlin("1.1") public actual typealias IllegalArgumentException = java.lang.IllegalArgumentException */ class UnSkilledException() : IllegalArgumentException("操作不当")
输出结果如下:
java.lang.IllegalStateException: Something is not good
先决条件函数有如下:
四、substring、split、replace,字符串遍历方法的使用
const val NAME = "I like Android development" const val WORK = "I,like,Android,development" fun main() { /** * substring * 字符串截取,substring函数支持IntRange类型(表示一个整数范围的类型)的参数, * util创建的范围不包括上限值 */ val substring = NAME.substring(7, 14) var str = NAME.substring(7 until 14) println(substring) println(str) /** * split * split函数返回的是list集合数据,List集合数据又支持解构语法特性,它允许你 * 在一个表达式里给多个变量赋值,解构常用来简化变量的赋值。 */ val data = WORK.split(",") //data[0] 取集合中的元素 /** * 这就是解构语法 */ val (origin, dest, proxy, detail) = WORK.split(",") println("$origin $dest $proxy $detail") val text = "The people's Republic of China" val text2 = text.replace(Regex("[aeiou]")) { when (it.value) { "a" -> "8" "e" -> "6" "i" -> "9" "o" -> "1" "u" -> "3" else -> it.value } } println(text) println(text2) /** * 遍历字符串 */ "The people's Republic of China".forEach { print("$it *") } }
输出结果如下:
Android Android I like Android development The people's Republic of China Th6 p61pl6's R6p3bl9c 1f Ch9n8 T *h *e * *p *e *o *p *l *e *' *s * *R *e *p *u *b *l *i *c * *o *f * *C *h *i *n *a *
五、- = =与===的比较
fun main() { /** * 字符串比较 * 在kotlin中,用==检查两个字符串的字符是否匹配,用===检查两个变量是否 * 指向内存堆上同一对象,而java中==做引用比较,做内容比较时用equals方法 */ val str1 = "Jason" val str2 = "jason".capitalize() println(str1 == str2) //true println(str1 === str2) //false }
六、数字类型的安全转换函数,Double转Int类型、以及格式化
fun main() { /** * 数字类型 * 和java一样,Kotlin中所有数字类型都是有符号的,也就是说既可以表示正数,也可以表示负数 * */ /** * 数字格式异常 NumberFormatException */ // val number1: Int = "8.98".toInt() /** * 安全转换函数 * Kotlin提供了toDoubleOrNull和toIntOrNull这样的安全转换函数,如果数值 * 不能正确转换,与其触发异常不如干脆返回null值 */ val number: Int? = "8.9".toIntOrNull() println(number) val number2: Double? = "0.91".toDoubleOrNull() println(number2) val number3: Double? = "1.99".toDouble() println(number3) /** * Double转Int * 四舍五入 */ println(8.99.roundToInt()) println(8.49.roundToInt()) /** * Double转Int * toInt:精度损失 */ println(8.956.toInt()) /** * 格式化字符串是一串特殊字符,它决定该如何格式化数据 */ val str = "%.2f".format(8.956) println(str) }
输出结果如下:
null 0.91 1.99 9 8 8 8.96