Suppose I have a delegate class that needs a class type and a Boolean. I have specific functionality in mind if the type of the property this delegate is used for is nullable. To keep it simple, let's say it's supposed to throw an error for nulls depending on the Boolean parameter.
class Sample<T: Any> (val type: KClass<T>,
val allowNulls: Boolean){
private var value: T?
operator fun getValue(thisRef: Any, property: KProperty<*>): T? {
return if (allowNulls)
value
else
value?: throw Exception("Value is null!")
}
operator fun setValue(thisRef: Any, property: KProperty<*>, value: T?) {
this.value = value
}
}
I want to create a reified function for easily generating an instance of this class that automatically determines whether the type should be nullable. Again, this is useful for a delegate that behaves differently for nullable properties. This would for example be used to allow different behavior depending on whether delegated properties were nullable:
val nullableString by sample<String?>()
val nonnullString by sample<String>()
val nullableString2: String? by sample()
val nonnullString2: String by sample()
How can I determine if the reified type is nullable? I don't see a way to access this information:
inline fun <reified T: Any> sample(): Sample<T>{
return Sample(T::class, /** T is nullable */)
}
If T
is a reified generic type parameter, you can find whether it's nullable or not with a simple, though not obvious at first sight check:
if (null is T) {
// T is nullable
}
However in your example T
has Any
upperbound, so the expression will always be false.
There's a very simple answer to this! But first:
Remember that the top type in Kotlin is Any?
(which is nullable). The non-nullable Any
is a subtype, and all non-nullable types descend from that. So a type is nullable if it's not a subtype of Any
.
So your generic <reified T: Any>
is already restricting to non-nullable types, and your function could just use false
!
However, if you relax that restriction, the test becomes just null is T
— after all, a type is nullable iff it includes null
as a value:
inline fun <reified T: Any?> sample(): Sample<T> {
return Sample(T::class, null is T)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With