Kotlin类型检查,Kotlin类型铸造
今天,我们将研究Kotlin类型检查和智能类型转换。
Kotlin类型检查
类型检查是在运行时检查数据类型的方法。
在Java中,我们使用instanceof
关键字来检查类型。
Kotlin使用关键字" is"和"!is"来分别检查某个属性是否为某种类型。
我们来看一个相同的示例代码。
var myProperty = "xyz" var otherProperty = 1 if(myProperty is String) { println("type is String") } else{ println("unknown type") } if(otherProperty !is Double) { println("not a string") } else{ println("unknown type") }
第一个if-else表达式将打印类型为String。
第二个将给出编译错误,因为Kotlin足够强大,可以在编译时自行确定类型。
让我们创建一个"任意"对象的列表,并检查每个元素的类型。
我们将使用when
语句检查for循环中每个元素的类型。
val anyList: List<Any> = listOf("theitroad.local", "Java", 101, 12.5f,12.5456789,false) for(value in anyList) { when (value) { is String -> println("String: '$value'. Capitalize :${value.capitalize()}") is Int -> println("Integer: '$value'") is Double -> println("Double: '$value'") is Float -> println("Float: '$value'") else -> println("Unknown Type") } }
以下是上述代码的输出。
Kotlin智能类型转换
智能类型转换是Kotlin中最有趣的功能之一。
如果条件满足,它将在右侧自动将属性转换为所需的类型。
fun getName(obj: Any?) { if (obj == null || obj !is String) { return } val string = obj println("Length of the string is ${string.length}") } getName(null) getName("Anupam")
在上面的代码中,我们不需要拆开可选选项。
如果智能强制转换通过了上述空检查器,则将自动解开Optional选项。
下面给出了以上代码打印的输出。
Java中相同的等效代码如下所示:
class MyJava { public static void main (String[] args) throws java.lang.Exception { //your code goes here MyJava mj = new MyJava(); mj.printStringLength("Anu"); } public void printStringLength(Object obj) { if (obj instanceof String) { String str = (String) obj; System.out.print("String substring is "); System.out.print(str.substring(1)); } } }
在上面的代码中,我们首先检查" instanceOf",然后显式键入强制类型转换。
借助Smart Casting,Kotlin使其变得更加简单。
二元运算符的智能转换
如以下代码所示,使用二进制运算符也可以进行智能转换。
fun newStringOnlyIfLength6(str: Any): Boolean { return str is String && str.length == 6 } print(newStringOnlyIfLength6("Kotlin")) //prints true fun stringOnlyIfLength6(str: Any): Boolean { return str !is String || str.length == 6 } print(stringOnlyIfLength6("Kotlin")) //prints true
在上面的代码中,在第一个函数中,如果第一个条件为true,则Kotlin类型会将第二个参数中的参数转换为相同类型。
类中智能转换
让我们创建实现如下所示接口的类:
import java.util.* fun main(args: Array<String>) { class Car : Vehicle { override fun printDetails() { println("AUDI Rocks") } } class Bike : Vehicle { override fun printDetails() { println("Bullet fires") } } val printMe: Vehicle val random = Random() fun rand(from: Int, to: Int): Int { return random.nextInt(to - from) + from } printMe = if (rand(0, 10) % 2 == 0) { Car() } else { Bike() } if (printMe is Car) { printMe.printDetails() } if (printMe is Bike) { printMe.printDetails() } } interface Vehicle { fun printDetails() }
随机函数会获得一个介于0到10之间的随机整数。
基于它是偶数还是奇数,接口都会从这两个类中创建实例化。
然后,is
运算符通过智能转换类的类型在if表达式中调用该方法。
注意:当Kotlin编译器无法保证检查和使用之间的值未发生变化时,它不会进行智能强制转换。
它总是对val属性进行智能转换,而对var属性则永远不会进行智能转换。
显式类型转换
我们可以使用as
运算符在Kotlin中显式键入类型属性。
val object: Any = "Hello World" val str: String = object as String println(str.length)
as运算符不安全。
在下面显示的场景中,它可能导致类似于Java的ClassCastException。
var y = null var x = y as String println(x) //crashes
x不是可为null的类型,因此不能将其设置为null。
对于这种情况,我们可以执行以下任一操作:
var y = null var x = y as String? println(x)
这使我们可以将x设置为null。
但是上述方法在以下情况下将失败:
var y = 5 var x = y as String? println(x) //crashes
因此,我们需要使用" as?"运算符,如果没有成功执行强制转换,则不设置运行时异常,而是将其设置为空值。
var y = 5 var x = y as? String println(x) //gives a null