Kotlin类型检查,Kotlin类型铸造

时间:2020-02-23 14:37:32  来源:igfitidea点击:

今天,我们将研究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