Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: Generics, reflection and the difference between type T and T:Any

If I try to access the javaClass of a generic type T the Kotlin compiler complains that T is not a subtype of kotlin.Any

class Foo<T> (val t: T ){
    val cls = t.javaClass // Error, T is not a subtype of kotlin.Any
}

If define T as a subtype of Any everything works ok.

class Bar<T:Any> (val t: T ){
    val cls = t.javaClass // OK
}

Q1) If type ´T´ is not a subtype of ´Any´ which class/classes can it be a subtype of ?

Q2) Do a javaClass exist for all instances of T and if so how do I access it ?

like image 224
Tomas Karlsson Avatar asked Feb 24 '16 12:02

Tomas Karlsson


People also ask

What is the difference between * and any in Kotlin generics?

When we define a collection with "*", it should contain the object of only that type. There should not be any mix and match between the data types inside a collection. If we use "Any", we can mix and match the data types, which means we can have multiple data types in a collection.

What is a generic type in Kotlin?

Generics are the powerful features that allow us to define classes, methods and properties which are accessible using different data types while keeping a check of the compile-time type safety. Creating parameterized classes – A generic type is a class or method that is parameterized over types.

How does Kotlin compare generic types?

In this article, we will see how we can get the type of a class that is used in Kotlin. There are no direct ways to do this in Kotlin. In order to check the generic type, we need to create an instance of the generic class<T> and then we can compare the same with our class.

What is the difference between T and E in Java generics?

Well there's no difference between the first two - they're just using different names for the type parameter ( E or T ). The third isn't a valid declaration - ? is used as a wildcard which is used when providing a type argument, e.g. List<?>


1 Answers

The default generic upper bound is not Any but Any?.

This also implies that it's not null-safe to get a javaClass from a nullable argument.

To get a javaClass from a generic type instance with Any? upper bound, you can cast it to Any:

val cls = (t as Any).javaClass //unsafe
val clsOrNull = (t as? Any)?.javaClass //safe
like image 184
hotkey Avatar answered Oct 22 '22 07:10

hotkey