一、is与!is操作符
1、使用 is 操作符或其否定形式 !is 在运行时检测对象是否符合给定类型。
fun main() {
var a = "1"
if(a is String) {
println("a是字符串类型:${a.length}")
}
// 或
val b = a is String
println(b)
}
二、"不安全的"转换操作符 as 与 as String?
1、如果转换失败,转换操作符会抛出一个异常。kotlin中的不安全转换使用中辍操作符 as 。
fun main() {
val a:String? = null
val b = a as String
println(b)
}
输出:
null 不能转换为String, 因为该类型不是可空的,如果转换时,不确定a是否可空(null),在类型转换的右侧使用可空类型进行转换:
fun main() {
val a:String? = null
val b = a as String?
println(b) // 输出 null
}
再来看一段代码:
fun main() {
// 会类型推断为 Int类型
val a:Any = 1
// Int类型转String 不管是否加了?都会抛出异常
val b = a as String?
println(b)
}
上边代码转换失败:
三、"安全的"可空转换操作符 as?
1、为了避免异常,还可以使用安全转换操作符 as? ,它可以在失败时,返回 null。
fun main() {
val a:String? = null
val b = a as? String
println(b) // 输出 null
}
四、总结
(1)as 转换操作符转换失败时,会抛出异常。
(2)as String? 转换 null时,不会抛出异常,会返回null,但是如果转换为别的类型,则会抛出异常。
(3)as? 转换失败时,不会抛出异常(比较抗霍霍)。
is底层,用脚想也能猜出来,应该是instanceof判断的,不会抛出任何异常:
boolean b = a instanceof String;
as和as String? 底层都是强转为String类型,没有做任何处理,所以抛出异常理所应当:
String b = (String)a;
再来看下as?底层代码:
public static final void main() {
Object a = 1;
// 把a包装成 Integer(自动装箱)
Integer var10000 = a;
// 判断 a 是否是 String 的实例,由于 a 实际上是 Integer 类型(装箱的 1),
// 这个条件总是 true,因此 var10000 被赋值为 null
if (!(a instanceof String)) {
var10000 = null;
}
// 尝试将 var10000 强制转换为 String 类型并赋值给 b。
// 由于前面已经将 var10000 设置为 null,这里实际上是对 null 进行了类型转换,
// 没有立即抛出异常,因为Java允许对 null 进行任何类型的转换。
String b = (String)var10000;
boolean var2 = false;
System.out.println(b);
}