一、首先看一下Java中关于空指针的问题处理
/**
* @author:wangdong
* @description: 先看一下java的空类型问题
*/
public class NullUnSafe {
public static void main(String[] args){
//为避免出现空指针导致程序崩溃
String name = getName();
if (null == name){
System.out.println("name is null");
}else {
System.out.println(getName().length());
}
}
public static String getName(){
return null;
}
}
二、如果在Kotlin中这样写的话,根本就不会编译通过
/**
* @author:wangdong
* @description:
*/
fun getName(): String{
return null
}
fun main(args: Array<String>) {
println(getName().length)
}
如果你想在判断方法是否等于null,编译器会说判断没有用,永远为false
if (getName() == null)
/**如果你偏要返回一个null*/
fun getName(): String ?{
return null
}
fun main(args: Array<String>) {
//就需要这么做了
//val name: String = getName() ?: return
//println(name.length)
val value: String ?= "helloworld"
//告诉编译器不用担心为null
println(value!!.length)
}
二、类型转换
例如:定义了两个类,一个Parent父类,一个Child子类,子类继承了父类,并且子类新增了一个自己的方法
package net.println.kotlin
/**
* @author:wangdong
* @description:
*/
fun main(args: Array<String>) {
//明确知道parent是Child的类型
val parent: Parent = Child()
if (parent is Child){
println(parent.name)
}
//即时直接说明了a为hello
val a: String ?= "hello"
//直接这样,编译器还是会说是不安全的,编译不通过
//println(a.length)
//那么就先判断下
if (a != null)
println(a.length)
//如果直接按照下面的做法
val p: Parent = Parent();
//用一个Child类型的child去接收,?=是允许p为空的意思,p as Child是p强制转成Child类型
//val child:Child ?= p as Child
//会抛Exception in thread "main" java.lang.ClassCastException: net.println.kotlin.Parent cannot be cast to net.println.kotlin.Child
// at net.println.kotlin.KotlinTypeCastKt.main(KotlinTypeCast.kt:26)
//如果不想让它抛异常,as后面加个?号,意思是如果转换失败了,不要跑异常,返回一个null赋值给child
val child:Child ?= p as? Child
println(child) //child 输出null
}
三、空类型的说明
任意类型都有可空和不可空两种
//val notNull: String = null //错误,不能为空
val notNull: String = "baidu" //正确
val nullable: String? = null //正确,可以为空
notNull.length //正确,不为空的值可以直接使用
//nullable.length //错误,可能为空,不能直接获取长度
nullable!!.length //正确,强制认定nullable不为空
nullable?.length //正确,如果nullable不为空,返回空
四、智能类型转换
Java的风格,转换失败会抛异常
val sub: SubClass = parent as SubClass
Kotlin的安全类型转换,加个
val child:Child ?= parent as? Child
kotlin特性:如果前面编译器明确知道了类型,在后面就不用再进行无用的类型转换了,直接使用即可
//明确知道parent是Child的类型
val parent: Parent = Child()
if (parent is Child){
直接使用child的方法
println(parent.name)
}
可以通过if判断
//即时直接说明了a为hello
val a: String ?= "hello"
//直接这样,编译器还是会说是不安全的,编译不通过
//println(a.length)
//那么就先判断下
if (a != null)
println(a.length)