Problem passing a Collection as "clazz: Class<T>"

Hi all,

I’m trying to call a method like this:
fun <T> dataAsObject(clazz: Class<T>): T { ...}

I’m trying to pass a Collection of a Complex Object when calling the method. E.g., Collection<Employer>

I’ve tried multiple options, but I don’t get it to work. E.g., passing a List<Employer>()::class.java, I got the error “Only classes are allowed on the left-hand side of a class literal”

Here is the full caller line:
val employers : Collection<Employer> = dataAsObject(List<Employer>::class.java)

What is the right way to get the Java Class for a Collection of objects in Kotlin?

Thanks for the help!

1 Like

This is the best that I could come up with:

import kotlin.reflect.*

val employers : Collection<String> = dataAsObject((typeOf<List<String>>().classifier!! as KClass<List<String>>).java)
fun <T> dataAsObject(clazz: Class<T>): T { return TODO() }
fun main() {
    println("hello world")
}

Isn’t the point here that types are not the same as classes?⠀ Or rather: all classes are types, but there are also many types which aren’t classes.⠀(Which makes types a superset of classes.)

In this case, String is a class (and also a type); and List is an interface, but that counts as a class for this purpose (and is also a type).⠀However, List<String> is a type but not a class; there’s no instance of Class which represents it.⠀(The same is true of String?, i.e. nullable String.)

So there is no Java class that represents a List<String>, only List.

Where is the dataAsObject() method from?⠀If it’s under your control, I’d suggest replacing the Class parameter with reified type parameter, which can represent List<String> or anything else (and will probably be simpler to call as the compiler will usually infer it).

(On the other hand, if it’s from a Java library, then you may be a bit stuck…)

It is a library. I don’t have control over that code.

I would like to understand what is going on under the hood. Any article or documentation you recommend me to read?

I followed up with the library owner and found that there is a method with the signature fun <T> extractValueAsObject(path: String, typeRef: TypeRef<T>): T which seems the right one to be used from Kotlin.

Thanks for your answers, you pointed me to the fact that there was something broken with the interface I was trying to use. :slight_smile:

1 Like

Thanks for looking into it. I found that there was another interface I could use. It seems the one I posted was not intended to be used from Kotlin code (it explains how hard was to try to make it work!).

1 Like