从Java到Kotlin学习笔记(2)|从Java到Kotlin学习笔记(2) - 空类型和智能类型转换

空类型

  • Java版
class NullUnSafe { public static void main(String[] args){ System.out.println(getName().length()); }public static String getName(){ return null; } }

上面这段程序会报Exception in thread "main" java.lang.NullPointerException
  • Kotlin版
fun getName(): String{ return null }fun main(args: Array) { println(getName().length) }

因为String是不可空类型(non-null type),编译器会警告Null can not be a value of non-null type String。
修改getName()方法
fun getName(): String{ return "shaoxia" }

编译通过,而且在这种情况中main方法中不再需要对getName()判空,也就是==if (getName() != null)== 可以省略,还是因为String是不可空类型(non-null type),意味着它的值不可能为null,如果写上判空语句,IDE会提示
Condition 'getName() != null' is always true
那如果要想跟Java一样可以返回null,就得在String后面加上问号"?",把String变为可空类型
class NullUnSafe { public static String getName() { return null; } public static void main(String[] args) { String name = getName(); if (name == null) { System.out.println("name is invalid"); } else { System.out.println(getName().length()); } }}

下面代码跟上面Java等价
fun getName(): String? { return null }fun main(args: Array) { val name = getName() if (name == null) { println("name is invalid") } else { println(name.length) } }

再进一步利用Kotlin特性
fun getName(): String? { return null }fun main(args: Array) { val name = getName() println(name?.length) //① }

【从Java到Kotlin学习笔记(2)|从Java到Kotlin学习笔记(2) - 空类型和智能类型转换】①的意思是,如果name不为null,那么输出name的长度,否则==name?.length==直接返回null

从Java到Kotlin学习笔记(2)|从Java到Kotlin学习笔记(2) - 空类型和智能类型转换
文章图片
image ?: 表达式 如果想实现当getName()为null就直接return的需求,则可以
fun main(args: Array) { val name: String = getName()?:return //① println(name.length) }

①语句的意思是,如果getName()为null时就执行后面的return语句,否则就把getName的结果赋值给不可空的String类型变量name
使用可空对象 从Java到Kotlin学习笔记(2)|从Java到Kotlin学习笔记(2) - 空类型和智能类型转换
文章图片
image 直接通过'.'使用可选类型对象,编译器是不会通过的,因为它认为对象可能是null,如果能肯定它不为null,要强行使用,可以在'.'之前加上两个叹号'!'
fun main(args: Array) { val value : String? = "Hello World!" println(value!!.length) }

类型转换
Java版
class Parent { }

class Child extends Parent { }

class TypeCast { public static void main(String[] args){ Parent parent = new Child(); //需要显式强转 System.out.println(((Child)parent).getName()); if(parent instanceof Child) { System.out.println(((Child) parent).getName()); } } }

java需要显示的强转,看起来很冗余,kotlin中只要提前告诉了编译器,会自动完成转换,就可以省去类似 ==((Child) parent)== 这样的代码了
fun main(args: Array) { val parent:Parent = Child() if (parent is Child){ println(parent.name) } }

==String?== 类型智能转换为==String==,不用再写双叹号了。
val string:String? = "Hello" if (string is String){ println(string.length) }

类型转换符号 as 与 as?
fun main(args: Array) { val parent: Parent = Parent() val child: Child? = parent as? Child println(child) val child2: Child? = parent as Child }

==as?== 是安全的类型转换符,如果转换失败会返回null给child变量,而==as==强制转换失败时会直接抛异常

从Java到Kotlin学习笔记(2)|从Java到Kotlin学习笔记(2) - 空类型和智能类型转换
文章图片
image 空类型总结 从Java到Kotlin学习笔记(2)|从Java到Kotlin学习笔记(2) - 空类型和智能类型转换
文章图片
image 智能类型转换总结 从Java到Kotlin学习笔记(2)|从Java到Kotlin学习笔记(2) - 空类型和智能类型转换
文章图片
image
从Java到Kotlin学习笔记(2)|从Java到Kotlin学习笔记(2) - 空类型和智能类型转换
文章图片
image

    推荐阅读