Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting Kotlin's KClass to regular Class in Java

Tags:

kotlin

I am trying call a regular Java method in a Java code as follows:

public <T> T proxy(KClass<T> kClass) { 
    // unfortunately nothing like getJavaClass() exists
    return (T) proxy(kClass.getJavaClass()); 
}

public <T> T proxy(Class<T> jClass) {
    return (T) context.getBean(jClass);
}

In Kotlin, you can call .java on each KClass. This is not the case here and I am unable to extract the Java Class object from KClass. Is there a way to do it?

EDIT: This is trivial in Kotlin, but I am looking for solution in Java code.

like image 543
Vojtěch Avatar asked Jul 21 '17 07:07

Vojtěch


People also ask

What does KClass represent?

Represents a class and provides introspection capabilities. Instances of this class are obtainable by the ::class syntax. See the Kotlin language documentation for more information.

Can I use Kotlin in Java?

Android Studio provides full support for Kotlin, enabling you to add Kotlin files to your existing project and convert Java language code to Kotlin. You can then use all of Android Studio's existing tools with your Kotlin code, including autocomplete, lint checking, refactoring, debugging, and more.

What is KClass Kotlin?

The KClass type is Kotlin's counterpart to Java's java. lang. Class type. It's used to hold references to Kotlin classes; you'll see what it lets you do with those classes in the “Reflection” section later in this chapter. The type parameter of KClass specifies which Kotlin classes can be referred to by this reference.


2 Answers

The functionality does exist, just not where it seems to, as java is an extension property.

Use the method JvmClassMappingKt.getJavaClass.

In Kotlin, extension methods (and property getters/setters) are implemented as static methods of their containing class. If you look at the source for .java (Ctrl+Q), you can see that it is implemented in JvmClassMapping.kt.

As the function is package-level and does not have a containing object, it is simply placed into the file [Filename]Kt which in this case is JvmClassMappingKt.

Here is the source of this extension property:

@Suppress("UPPER_BOUND_VIOLATED")
public val <T> KClass<T>.java: Class<T>
    @JvmName("getJavaClass")
    get() = (this as ClassBasedDeclarationContainer).jClass as Class<T>

As you can see, the method's name is renamed on the JVM to getJavaClass.

In your case, you can try:

public <T> T proxy(KClass<T> kClass) { 
    return (T) proxy(JvmClassMappingKt.getJavaClass(kClass)); 
}
like image 55
Salem Avatar answered Oct 26 '22 09:10

Salem


You can try to use javaObjectType on your KClass

The explanation:

Returns a Java [Class] instance corresponding to the given [KClass] instance. In case of primitive types it returns corresponding wrapper classes.

E.g.

Boolean::class.javaObjectType

like image 25
EzYy Avatar answered Oct 26 '22 08:10

EzYy