Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class literal syntax for parameterized classes in Kotlin

Tags:

kotlin

I'm trying to mock a function in Kotlin

Mockito.mock(Function2<Int, Int, Unit>::class.java)

and it says "Only classes are allowed on the left hand side of a class literal". What's the proper way to obtain a reference to a statically known parameterized class? For now I live with an ugly cast

Mockito.mock(Function2::class.java) as (Int, Int) -> Unit
like image 835
Yaroslav Avatar asked Sep 28 '15 15:09

Yaroslav


People also ask

What is the :: in Kotlin?

?: takes the right-hand value if the left-hand value is null (the elvis operator). :: creates a member reference or a class reference.

How do you get the generic parameter class 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.

How do you declare a class variable in Kotlin?

Variable declaration. Kotlin uses two different keywords to declare variables: val and var . Use val for a variable whose value never changes. You can't reassign a value to a variable that was declared using val .

What is the correct syntax for constraints in generic functions in Kotlin?

The most common type of constraint is an upper bound, which corresponds to Java's extends keyword: fun <T : Comparable<T>> sort(list: List<T>) { ... }


1 Answers

The error is correct and the solution you provided is the intended one. The rationale here is that since generic type arguments are not reified at runtime, you can only obtain an object representing a class, not a type.

There's a workaround though: if you use the class literal syntax through a reified type parameter, substituting it with the desired type at the call site, you'll get the same KClass object but with the actual arguments you've provided. In your case you can declare the following function:

inline fun <reified T : Any> mock(): T = Mockito.mock(T::class.java) as T

And use it like this:

val f = mock<(Int, Int) -> Unit>()
like image 128
Alexander Udalov Avatar answered Dec 31 '22 23:12

Alexander Udalov