- Android Development with Kotlin
- Marcin Moskala Igor Wojda
- 503字
- 2021-07-02 18:48:35
Type smart casts
Let's represent the Animal and Fish classes from the previous section:

Let's assume we want to call the isHungry method and we want to check if the animal is an instance of Fish. In Java, we would have to do something like this:
//Java if (animal instanceof Fish){ Fish fish = (Fish) animal; fish.isHungry(); //or ((Fish) animal).isHungry(); }
The problem with this code is its redundancy. We have to check if the animal instance is Fish and then we have to explicitly cast animal to Fish after this check. Wouldn't it be nice if the compiler could handle this for us? It turns out that the Kotlin compiler is really smart when it comes to casts, so it will handle all those redundant casts for us, using the smart casts mechanism. Here is an example of smart casting:
if(animal is Fish) { animal.isHungry() }
Android Studio will display proper errors if smart casting is not possible, so we will know exactly whether we can use it. Android Studio marks variables with a green background when we access a member that required a cast.

In Kotlin, we don't have to explicitly cast an animal instance to Fish, because after the type check, the Kotlin compiler will be able to handle casts implicitly. Now inside the if block, the variable animal is cast to Fish. The result is then exactly the same as in the previous Java example (the Java instance of the operator is called in Kotlin). This is why we can safely call the isHungry method without any explicit casting. Notice that in this case, the scope of this smart cast is limited by the if block:
if(animal is Fish) { animal.isHungry() //1 } animal.isHungry() //2, Error
- In this context, the animal instance is Fish, so we can call the isHungry method.
- In this context, the animal instance is still Animal, so we can't call the isHungry method.
There are, however, other cases where the smart cast scope is larger than a single block, as in the following example:
val fish:Fish? = // ... if (animal !is Fish) //1 return animal.isHungry() //1
- From this point, animal will be implicitly converted to a non-nullable Fish.
In the preceding example, the whole method would return from the function if animal is not Fish, so the compiler knows that animal must be Fish across the rest of the code block. Kotlin and Java conditional expressions are evaluated lazily.
This means that in the expression condition1() && condition2(), the method condition2 will be called only when condition1 returns true. This is why we can use a smart cast type on the right-hand side of the conditional expression:
if (animal is Fish && animal.isHungry()) { println("Fish is hungry") }
Notice that if the animal was not Fish, the second part of the conditional expression would not be evaluated at all. When it is evaluated, Kotlin knows that animal is Fish (smart cast).
- Designing Machine Learning Systems with Python
- 深度實踐OpenStack:基于Python的OpenStack組件開發
- Android Jetpack開發:原理解析與應用實戰
- 潮流:UI設計必修課
- Python Geospatial Development(Second Edition)
- Quarkus實踐指南:構建新一代的Kubernetes原生Java微服務
- Building a Quadcopter with Arduino
- Protocol-Oriented Programming with Swift
- C++20高級編程
- Visual Basic程序設計習題與上機實踐
- TypeScript 2.x By Example
- JavaScript悟道
- Ext JS 4 Plugin and Extension Development
- Moodle 3.x Developer's Guide
- Kotlin程序員面試算法寶典