Kotlin

类型检测与类型转换:"is" 与 "as"

2020-11-18  本文已影响0人  码农修行之路

"is" 与 "as"

"is" 操作符 代表对象是否是该指定类型
"!is" 操作符 代表对象是否不是该指定的类型
例如:

fun main() {
    val str: Any = "小黄";
    // 变量str是Any类型 通过is智能转换为String
    if (str is String) {
        println("是String子类型")
    } else {
        println("非String子类型")
    }
    // 或者
    if (str !is Int) {
        println("不是Int类型")
    } else {
        println("是Int类型")
    }
}
if(str instanceof String ) {
    Log.i("test"," 是其子类 ");
}

智能转换 应用于while循环 when表达式:

when (str) {
    is String -> println("是字符串类型")
    is Int -> println("是Int类型")
    is IntArray -> println("是Int数组类型")
    else -> println("其它未检测的类型")
}

智能转换规则:

  1. val ->局部变量 可以 局部委托属性 不可
  2. val ->属性 如果属性是private或internal 再或者该检测在声明属性的同一模块中执行 可以 open的属性或具有自定义getter的属性 不可
  3. var ->局部变量 如果变量在检测和只用之间没有修改 没有在会修改它的lambda表达式中捕获,并且不是局部委托属性 可以
  4. var ->属性 绝不可能(因为该变量随时可以被其它代码修改)

"不安全的"转换操作符

fun main() {
    val y: String? = null;
    // 异常 java.lang.NullPointerException: null cannot be cast to non-null type kotlin.String
    val x: String = y as String 
}
fun main() {
    val y: String? = null;
    // 异常 java.lang.NullPointerException: null cannot be cast to non-null type kotlin.String
    val x: String? = y as String?
}

"安全的"(可空)转换操作符

fun main() {
    //val y1: Int? = null;
    val y1: Int = 0;
    // java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    //val x1: String = y1 as String
    // 使用安全转换操作符 可以处理类型转换异常问题
    val x1: String? = y1 as? String
    println(x1)
}

类型擦除

KT在编译的时确保涉及泛型操作的类型安全性,而在运行时,泛型类型的实例并未带有关于它们实际类型参数的信息 例如:List<Foo> 会被擦除为 List<*> 通常,在运行时无法检测一个实例是否属于带有某个类型参数的泛型类型
为此 编译器会禁止由于类型擦除而无法执行的is检测 例如 ints is List<Int> 或者 list is T(类型参数) 当然,可以对一个实例检测星投影的类型:

fun main() {
    val list = listOf(22, 33, 44, 55)
    if (list is List<*>) {
        list.forEach {
            println(it)
        }
    }

    val body1 = Body("小黄")
    val body2 = Body("小杨")
    val body3 = Body("小王")
    var listBody = listOf(body1, body2, body3)

    if (listBody is List<*>) {
        listBody.forEach {
            println(it)
        }
    }
}
data class Body(val name: String)
fun main() {
    val list1 = arrayListOf("小黄", "小李", "小朱")
    handlerStrings(list1);
    val listA = arrList as List<String>
    listA.forEachIndexed { index, value ->
        println(" list $index $value ")
    }
}
fun handlerStrings(arrList: ArrayList<String>) {
    if (arrList is List<String>) {
        // arrList 会智能转换为 List<String>
        arrList.forEach {
            println(it)
        }
    }
}

执行结果:
arrayList 0 小黄
arrayList 1 小李
arrayList 2 小朱
list 0 小黄
list 1 小李
list 2 小朱

上一篇下一篇

猜你喜欢

热点阅读