从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) //①
}

①的意思是,如果name不为null,那么输出name的长度,否则==name?.length==直接返回null


image

?: 表达式

如果想实现当getName()为null就直接return的需求,则可以

fun main(args: Array) {
    val name: String = getName()?:return //①
    println(name.length)
}

①语句的意思是,如果getName()为null时就执行后面的return语句,否则就把getName的结果赋值给不可空的String类型变量name

使用可空对象

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==强制转换失败时会直接抛异常


image

空类型总结

从Java到Kotlin学习笔记(2) - 空类型和智能类型转换_第1张图片
image

智能类型转换总结

从Java到Kotlin学习笔记(2) - 空类型和智能类型转换_第2张图片
image

从Java到Kotlin学习笔记(2) - 空类型和智能类型转换_第3张图片
image

你可能感兴趣的:(从Java到Kotlin学习笔记(2) - 空类型和智能类型转换)