Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

kotlin reflection check nullable types

How can I test if a KType variable holds a value of a nullable kotlin type, (e.G. Int?)?

I have

var type: KType 

variable coming from a KProperty<*>.returnType and I need to detect if it is equal to certain kotlin types (Int, Long, etc). This works with:

when (type) {
    Int::class.defaultType -> ...
    Long::class.defaultType -> ...
    else -> ...
}

but this only works for non-nullable types, so the first branch does not match to Int? However I was yet unable to figure out how I could detect is type is Int? other then to obvious but not so nice

type.toString().equals("kotlin.Int?")
like image 339
Lajos Gathy Avatar asked Mar 11 '16 17:03

Lajos Gathy


People also ask

How do you check null in Kotlin?

You can use the "?. let" operator in Kotlin to check if the value of a variable is NULL. It can only be used when we are sure that we are refereeing to a non-NULL able value.

How do you ensure null safety in Kotlin?

Kotlin has a safe call operator (?.) to handle null references. This operator executes any action only when the reference has a non-null value. Otherwise, it returns a null value. The safe call operator combines a null check along with a method call in a single expression.

What is Nullability in Kotlin?

In Kotlin, there's a distinction between nullable and non-nullable types: Nullable types are variables that can hold null . Non-null types are variables that can't hold null .

What is null safety in Kotlin explain it with example?

Kotlin null safety is a procedure to eliminate the risk of null reference from the code. Kotlin compiler throws NullPointerException immediately if it found any null argument is passed without executing any other statements. Kotlin's type system is aimed to eliminate NullPointerException form the code.


1 Answers

As you can see from the KType API documentation, its interface is far from complete. Currently almost for any operation you have to resort to Java reflection with the .javaType extension property available on KType instances. (By the way, this is surely going to be addressed in Kotlin 1.1.)

In your case, you have to check if the type is nullable and its Java type is equal to that of the required primitive class, e.g.:

val isNullableInt = type.isMarkedNullable &&
                    type.javaType == Int::class.defaultType.javaType

I can also present a funny workaround which may be more suitable for your use case: you can declare a private function with the needed type and use reflection to compare against the return type of that function at runtime:

// Only return type of this function is used
fun _nullableInt(): Int? =
    TODO()  // Doesn't matter, it never gets called

...

val isNullableInt = type == ::_nullableInt.returnType
like image 67
Alexander Udalov Avatar answered Oct 10 '22 15:10

Alexander Udalov