kotlin 空类型和类型智能转换

空指针异常是java永远的痛

package com.test.com.java.utils;

/**
 * Created by jingwen on 19/4/13.
 */
public class Tools {
    /**
     *
     * @param type 0,1,2
     * @return
     */
    public static String getCarNameByType(int type){
        String name = null;
        switch (type){
            case 0:
                name = "宾利";
                break;
            case 1:
                name = "比亚迪";
                break;
            case 2:
                name = "北汽";
                break;
        }
        return name;
    }

}

//主程序

package com.test.com.java.utils;

/**
 * Created by jingwen on 19/4/13.
 */
public class TestMain {
    public static void main(String[] args){
        System.out.println();
        String carName = Tools.getCarNameByType(9);
        System.out.println(carName);
        System.out.println(carName.length());
    }
}

控制台输出:

Exception in thread "main" java.lang.NullPointerException
null
	at com.test.com.java.utils.TestMain.main(TestMain.java:11)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Process finished with exit code 1

kotlin 非常牛B的解决了NullPointerException

在kotlin中不允许你赋值为空.

package com.base

/**
 * Created by jingwen on 19/4/13.
 */


fun getCarNameByType( type:Int)
: String {


    return "宾利"
}

fun main(args: Array<String>) {

 var carName:String = getCarNameByType(1)
    println(carName)

}

如果需要返回为空值需要在函数类型后面加?,使用的所有地方都要加?

package com.base

/**
 * Created by jingwen on 19/4/13.
 */


fun getCarNameByType(): String? {
    return null
}

fun main(args: Array<String>) {

 var carName:String? = getCarNameByType()
    println(carName?.length)

}

输出结果:

null

Process finished with exit code 0

明知道字符串不为空,可以使用!!来告诉编译器

package com.base

/**
 * Created by jingwen on 19/4/13.
 */


fun getCarNameByType(): String? {
    return null
}

fun main(args: Array<String>) {

 var carName:String? = "jingwen";
    println(carName!!.length)

}

运行结果:

7

Process finished with exit code 0

类型转换:

java代码

package com.test;

/**
 * Created by jingwen on 19/4/13.
 */
 class Parent {
    
}


/**
 * Created by jingwen on 19/4/13.
 */
 class Child extends Parent {
    public void childSay(){
        System.out.println("Child say hello world");
    }
}



/**
 * Created by jingwen on 19/4/13.
 */
public class TestCast {
    public static void main(String[] args){
        Parent o = new Child();
        ((Child)o).childSay();

        if (o instanceof Child){
            ((Child) o).childSay();//明明知道是Child对象,就不应该强转了,java太傻了,kotlin就比较聪明
        }
    }
}
package com.base

/**
 * Created by jingwen on 19/4/13.
 */

open class Parent{

}

class Child :Parent(){
    init {

    }
    fun childsay():Unit{
        println("child say hello world")
    }
}

fun main(args: Array<String>) {
    var p:Parent = Child()
    if(p is Child){
        p.childsay()//kotlin是不是很牛逼哈
    }

    //类型转换
    var  c = p as Child
    c.childsay()

}

安全的类型转换:

kotlin也是有脾气的也会出现类型转换异常

package com.base

/**
 * Created by jingwen on 19/4/13.
 */

open class Parent{

}

class Child :Parent(){
    init {

    }
    fun childsay():Unit{
        println("child say hello world")
    }
}

fun main(args: Array<String>) {
//    var p:Parent = Child()
//    if(p is Child){
//        p.childsay()
//    }
//
//    //类型转换
//    var  c = p as Child
//    c.childsay()

    var  p:Parent = Parent()
    var  c:Child = p as Child
    c.childsay()

}

输出结果:

Exception in thread "main" java.lang.ClassCastException: com.base.Parent cannot be cast to com.base.Child
	at com.base.TestcastKt.main(testcast.kt:31)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Process finished with exit code 1

你不让我类型你也别让我出现ClassCastException啊

解决方案: as?

package com.base

/**
 * Created by jingwen on 19/4/13.
 */

open class Parent{

}

class Child :Parent(){
    init {

    }
    fun childsay():Unit{
        println("child say hello world")
    }
}

fun main(args: Array<String>) {
//    var p:Parent = Child()
//    if(p is Child){
//        p.childsay()
//    }
//
//    //类型转换
//    var  c = p as Child
//    c.childsay()

    var  p:Parent = Parent()
    var  c:Child? = p as? Child
    if (c != null) {
        c.childsay()
    } else{
        println("c=="+c)
    }

}
c==null

Process finished with exit code 0

总结:

val notNull:String = null//编译错误,规定不能为空

val nullable:String? = null//编译正确,?可能为空

notNull.length //编译正确,不为空的值可以直接使用

nullable.length//编译错误,可能为空的值,不能直接使用length方法.会出现NullPointerException

nullable?.length//编译正确, 如果为空,这个表达式的值为空

nullable!!.length//编译正确,可以骗过编译器

val str:String?=null
println(str!!.length)

照样程序崩溃:

Exception in thread "main" kotlin.KotlinNullPointerException
    at com.base.TestcastKt.main(testcast.kt:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

java Style类型转换

val sub:SubClass = parent as SubClass

类似于java转换失败就会报异常

安全的类型转换

val sub:SubClass? = parent as? SubClass

程序不会崩溃

sub 转换失败后,sub这个对象是空值. 

智能类型转换

if( parent is SubClass){

parent.childSay()//编译器智能推导出是SubClas的对象, 智能转换了

}

if(parent != null){

parent.childSay()//跟java一样 ,可以大胆调用不会出现空指针

}

猜你喜欢

转载自blog.csdn.net/jingwen3699/article/details/89284418