4.8 类型检测与类型转换
4.8.1 is,!is运算符
is运算符可以检查对象是否与特定的类型兼容(“兼容”的意思是:此对象是该类型,或者派生于该类型)。
is运算符用来检查对象(变量)是否属于某数据类型(如Int、String、Boolean等)。C#里面也有这个运算符。
is
运算符类似Java的instanceof
:
@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)
public class TypeSystemDemo {
@org.junit.Test
public void testVoid() {
if ("abc" instanceof String) {
println("abc is instanceof String");
} else {
println("abc is not instanceof String");
}
}
void println(Object obj) {
System.out.println(obj);
}
}
在Kotlin中,我们可以在运行时通过使用 is
操作符或其否定形式 !is
来检查对象是否符合给定类型:
>>> "abc" is String
true
>>> "abc" !is String
false
>>> null is Any
false
>>> null is Any?
true
代码示例:
@RunWith(JUnit4::class)
class ASOperatorTest {
@Test fun testAS() {
val foo = Foo()
val goo = Goo()
println(foo is Foo) //true 自己
println(goo is Foo)// 子类 is 父类 = true
println(foo is Goo)//父类 is 子类 = false
println(goo is Goo)//true 自己
}
}
open class Foo
class Goo : Foo()
类型自动转换
在Java代码中,当我们使用str instanceof String
来判断其值为true
的时候,我们想使用str变量,还需要显式的强制转换类型:
@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)
public class TypeSystemDemo {
@org.junit.Test
public void testVoid() {
Object str = "abc";
if (str instanceof String) {
int len = ((String)str).length(); // 显式的强制转换类型为String
println(str + " is instanceof String");
println("Length: " + len);
} else {
println(str + " is not instanceof String");
}
boolean is = "1" instanceof String;
println(is);
}
void println(Object obj) {
System.out.println(obj);
}
}
而大多数情况下,我们不需要在 Kotlin 中使用显式转换操作符,因为编译器跟踪不可变值的 is-检查,并在需要时自动插入(安全的)转换:
@Test fun testIS() {
val len = strlen("abc")
println(len) // 3
val lens = strlen(1)
println(lens) // 1
}
fun strlen(ani: Any): Int {
if (ani is String) {
return ani.length
} else if (ani is Number) {
return ani.toString().length
} else if (ani is Char) {
return 1
} else if (ani is Boolean) {
return 1
}
print("Not A String")
return -1
}
4.8.2 as运算符
as运算符用于执行引用类型的显式类型转换。如果要转换的类型与指定的类型兼容,转换就会成功进行;如果类型不兼容,使用as?
运算符就会返回值null。
代码示例:
>>> open class Foo
>>> class Goo:Foo()
>>> val foo = Foo()
>>> val goo = Goo()
>>> foo as Goo
java.lang.ClassCastException: Line69$Foo cannot be cast to Line71$Goo
>>> foo as? Goo
null
>>> goo as Foo
Line71$Goo@73dce0e6
我们可以看出,在Kotlin中,子类是禁止转换为父类型的。
按照Liskov替换原则,父类转换为子类是对OOP的严重违反,不提倡、也不建议。严格来说,父类是不能转换为子类的,子类包含了父类所有的方法和属性,而父类则未必具有和子类同样成员范围,所以这种转换是不被允许的,即便是两个具有父子关系的空类型,也是如此。
当前内容版权归 JackChan1999 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 JackChan1999 .