Мне нужно динамически загружать классы во время выполнения в Kotlin.Я хотел бы проверить, что они реализуют мой интерфейс, и если так, все зеленые.К сожалению, «умные броски» Котлина меня подводят:
var className = "some.class.Name"
val unsafeClass = Class.forName(className).kotlin
require(unsafeClass.isSubclassOf(MyInterface::class)) {
"Class '$className' is not a MyInterface"
}
val safeClass = unsafeClass as KClass<MyInterface>
^^^^^^^^^^^^^^^^^^^^^^
Unchecked cast: KClass<out Any!> to KClass<MyInterface>
Я четко проверяю, реализует ли класс данный интерфейс.Могу ли я перефразировать этот код, чтобы избежать предупреждения?
Я пытался проверить с is KClass<MyInterface>
, но я получаю ошибку стирания типа (очевидно, потому что информация общего типа исчезает во время выполнения.)
Редактировать: чтобы уточнить, мое приложение должно читать имена классов "some.class.Name"
при запуске, во время настройки;загрузить эти классы;убедитесь, что они удовлетворяют интерфейсу;и сохраните ссылку Class или KClass для дальнейшего использования.Во время выполнения он будет использовать эти ссылки для создания объектов, используя cls.createInstance()
или что-то подобное.
Мой вопрос: есть ли способ сделать это без получения небезопасных предупреждений о приведении?
Я могу либополучить предупреждение во время конфигурации, когда я приведу KClass<*>
к KClass<MyInterface>
(даже если я require
d, чтобы класс был подклассом), но потом я не получаю предупреждения, потому что .createInstance()
на KClass<MyInterface>
ссылка на класс возвращает проверенный тип MyInterface
экземпляр.
Или я могу сохранить ссылки как KClass<*>
, без предупреждений во время конфигурации, но тогда я получу предупреждение в том месте, где ясоздать экземпляры, потому что мне нужно небезопасно привести Object
экземпляров к MyInterface
.
Есть ли какое-либо решение, которое удовлетворит компилятор?