Kotlin Tutoial
Basics
Control Flow
Array & String
Functions
Collections
OOPs Concept
Exception Handling
Null Safety
Regex & Ranges
Java Interoperability
Miscellaneous
Android
In Kotlin, type checking and smart casting simplify the process of checking types and casting variables, leading to more concise and readable code. In this tutorial, we'll dive into these concepts.
is
and !is
The is
keyword is used to check if a variable belongs to a particular type. The !is
keyword checks if a variable does not belong to a type.
fun getType(input: Any) { when(input) { is String -> println("It's a String!") is Int -> println("It's an Integer!") is Double -> println("It's a Double!") else -> println("Unknown type!") } }
In the example above, we're checking the type of input
using the is
keyword inside a when
expression.
One of the key features of Kotlin is smart casting. Once you check a variable's type, Kotlin automatically casts it to that type within the scope of that check. This means you don't have to do explicit casting as you often would in languages like Java.
fun getStringLength(input: Any): Int? { if (input is String) { // input is automatically cast to String within this scope return input.length } return null }
In the function above, after we check if input
is a String
, we can directly call input.length
without any explicit casting. Kotlin understands that within that block, input
can only be a String
.
as
Operator for CastingIf you're sure about the type of a variable and want to cast it, you can use the as
keyword. However, be careful: if the type is not what you expect, a ClassCastException
will be thrown.
val obj: Any = "Hello" val str: String = obj as String
For safe casting, you can use as?
, which returns null
if the casting isn't possible:
val obj: Any = 123 val str: String? = obj as? String // str will be null, no exception thrown
Smart casting works in most cases, but there are scenarios where Kotlin cannot smart cast. This is mainly in cases where the compiler cannot guarantee the variable hasn't changed its type between the check and the usage. This can happen with:
In such cases, you'll need to use explicit casting or other strategies.
Type checking and smart casting in Kotlin are powerful features that result in cleaner, more concise, and safer code. They simplify many common patterns you'll encounter and help prevent type-related errors. Always remember to be cautious with explicit casting, especially in scenarios where you're unsure of the variable's actual type.
Using 'is' operator for type checking in Kotlin:
is
operator checks if an object is an instance of a particular type.val result: Any = "Hello, Kotlin!" if (result is String) { println(result.length) }
Checking and casting types with 'as' operator in Kotlin:
as
operator is used for explicit casting.val anyValue: Any = "Kotlin" val stringValue: String = anyValue as String
Smart casting and automatic type conversion in Kotlin:
fun printLength(value: Any) { if (value is String) { println(value.length) // Smart cast to String } }
Working with nullable types and type checking in Kotlin:
as?
.val nullableValue: String? = "Nullable" val length: Int? = nullableValue as? String)?.length
Combining type checking and when expressions in Kotlin:
when
expressions for concise type checking.fun printType(value: Any) { when (value) { is String -> println("String") is Int -> println("Int") else -> println("Unknown Type") } }
Type checking in Kotlin and polymorphism:
interface Shape class Circle : Shape fun processShape(shape: Shape) { if (shape is Circle) { // Handle Circle-specific logic } }
Type inference and smart casting in Kotlin:
val value: Any = "Inferred Type" if (value is String) { println(value.length) // Smart cast to String }
Custom type checking functions in Kotlin:
fun isEven(number: Int): Boolean = number % 2 == 0 if (isEven(4)) { // Handle even number logic }
Type checking with sealed classes in Kotlin:
sealed class Result class Success : Result() class Error : Result() fun processResult(result: Result) { when (result) { is Success -> println("Success") is Error -> println("Error") } }
Type checking and extension functions in Kotlin:
fun String.isPalindrome(): Boolean { return this == this.reversed() } val palindromeCheck = "radar".isPalindrome()
Type checking and reflection in Kotlin:
val obj: Any = "Reflection" val className = obj::class.simpleName println("Type: $className")