天天看點

Kotlin-31-is as 對比instanceof

目錄

1、instanceof(類型檢查)

2、is (類型檢查)

3、as(類型強轉)

4、as?

5、類型轉換封裝方法

1、instanceof(類型檢查)

我們常會在Java中見到如下的代碼:

我們拿到一個父類型Animal的對象時,會先用instanceof檢查這個對象是否是我們想要的子類型Dog,如果是的話,然後就是對這個類型進行強轉,然後再做Dog應該做的事情。

public class Test1 {
    public static void main(String[] args) {
        Animal animal=new Dog();
        if (animal instanceof Dog){
            Dog dog= (Dog) animal;
            dog.bark();
        }
    }
}
//輸出結果
汪汪...

open class Animal() {
    var name: String = "a"
    var age: Int = 3
}

class Dog : Animal() {
    var color: String = "blue"
    fun bark() {
        println("汪汪...")
    }
}
           

2、is (類型檢查)

那麼Kotlin中怎麼實作上面的類型檢查呢?

那就是is關鍵字,而且當我們類型檢查是Dog類型的時候,我們不再需要将Animal父類型強轉成Dog子類型,Kotlin會幫我們自動轉換成我們想要的類型。

我們看到編譯後以後的代碼,和我們前面Java代碼是一樣的,隻是Koltin幫我們自動實作了這一步。

fun main() {
    val animal: Animal = Dog()
    if (animal is Dog) {
        animal.bark()
    }
}
//輸出結果
汪汪...

//編譯後的Java代碼
 public static final void main() {
      Animal animal = (Animal)(new Dog());
      dogBark(animal);
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }

   public static final void dogBark(@NotNull Animal animal) {
      Intrinsics.checkParameterIsNotNull(animal, "animal");
      if (animal instanceof Dog) {
         ((Dog)animal).bark();
      }

   }
           

3、as(類型強轉)

當然,我們有些情況是需要手動進行類型強轉的,Koltin中進行類型強轉的關鍵字就是as。

as? 

fun main() {
    val animal:Animal=Dog()
    
    val dog:Dog= animal as Dog
}
           

4、as?

當 animal as Dog 中animal如果是null的話,會出現上面情況呢?那肯定是報錯了?如下:

fun getDog(): Animal? {
    return null
}
fun main() {
    val animal: Animal ?= getDog()
    val dog:Dog= animal as Dog
    dog.bark()
}

//異常資訊
Exception in thread "main" kotlin.TypeCastException: 
null cannot be cast to non-null type com.yobo.yobo_kotlin.test36.Dog
           

那麼我們怎麼解決這種異常呢?

那就是 as?可null的強轉符号,如下:這樣運作就不會報錯了。

fun getDog(): Animal? {
    return null
}
fun main() {
    val animal: Animal ?= getDog()
    val dog:Dog?= animal as? Dog
    dog?.bark()
}
           

5、類型轉換封裝方法

在我們整個項目的編寫過程中,我們會經常遇到類型轉換,然後我們會不斷的重複寫is 語句,為了避免重複的代碼, 我們這裡結合範型封裝,寫出一個類型轉換的靜态工具方法。

//Kotlin代碼
fun main() {
    val animal: Animal = Dog()
    val dog = CastUtil.cast<Dog>(animal)
    dog?.bark()
}

object CastUtil {
    @JvmStatic
    fun <T> cast(father: Any): T? = father as? T
}
//輸出結果
汪汪...

//Java代碼
public class Test1 {
    public static void main(String[] args) {

        Animal animal=new Dog();
        Dog dog=CastUtil.cast(animal);
        dog.bark();
    }
}
//輸出結果
汪汪...