Синтаксис Котлина для вывода общего супертипа из подтипа

Пытаясь называть существующий Java-код, ожидающий Class как параметр, я пробовал код в соответствии с этим в Kotlin:

 package com.example //Acutally imported Java code in someone elses's library abstract class JavaCode<T> { fun doTheThing(thing: Class<JavaCode<T>>) { //Does work } } //My code class KotlinCode : JavaCode<String>() { fun startTheThing() { doTheThing(KotlinCode::class.java) } // ^ Type inference failed. Expected type mismatch } 

Но это не скомпилируется со следующей ошибкой:

 Type inference failed. Expected type mismatch: inferred type is Class<KotlinCode> but Class<JavaCode<String>> was expected 

Поэтому я попытался заставить бросок (как предлагается в этом ответе ):

 hello(GenericArgument::class.java as Class<Callable<String>>) 

Но у этого есть предупреждение:

 Unchecked cast: Class<KotlinCode> to Class<JavaCode<String>> 

Итак, какой правильный синтаксис использовать? Связано ли это ?

В вашем коде есть несколько проблем.

Во-первых, Callable<String?> Не равно Callable<String> . Callable<String?> Означает, что аргумент может быть String или null но Callable<String> – только String .

Во-вторых, Class<GenericArgument> не реализует Class<Callable<String>> но GenericArgument реализует Callable<String> . они разные. Вы можете изменить его, чтобы вместо этого использовать общий.

 private fun <T : Callable<String>> hello(callable: Class<T>) { System.out.println(callable.toString()) } 

Теперь общий параметр связан с помощью Callable<String> .

В-третьих, callable.toString() вероятно, не делает то, что вы хотите. callable.toString() вызовет toString() класса вместо объекта, например class com.example.yourclass . Если вы хотите вызвать объект toString() . Это правильно.

 override fun call(): String { hello(GenericArgument()) return "value" } private fun <T : Callable<String>> hello(callable: T) { System.out.println(callable.toString()) } 

Более того, Kotlin позволяет передавать функцию в качестве параметра или использовать SAM для интерфейса. Реализация для Callable не требуется.

Изменить: Поскольку op обновил вопрос.

 @Suppress("UNCHECKED_CAST") fun <T, U : JavaCode<T>> JavaCode<T>.doTheThing2(thing: Class<U>) { doTheThing(thing as Class<JavaCode<T>>) }