Получение класса списка с общим типом: List <Number> :: class

У меня есть типизированный класс Builder<T> который принимает аргумент конструктора Class<T> поэтому я могу сохранить тип вокруг. Это класс, который я использую много в Java-коде, поэтому я не хочу менять подпись. Когда я пытаюсь использовать конструктор следующим образом:

Builder<List<Number>>(List<Number>::class)

Я получаю сообщение об ошибке: «Только классы разрешены в левой части литерала класса»

Любой способ разрешить это? Я не могу изменить конструктор для Builder , слишком много java-классов полагаются на него.

Я понимаю проблему стирания всего типа, я просто хочу сделать компилятор счастливым.

Solutions Collecting From Web of "Получение класса списка с общим типом: List <Number> :: class"

Из-за родового типа стирание List имеет единую реализацию для всех своих общих экземпляров. Вы можете получить только класс, соответствующий типу List<*> , и тем самым создать только Builder<List<*>> .

Этот экземпляр компоновщика подходит для создания списка чего-то . И снова из-за стирания типа, что это такое, вы можете решить самостоятельно с помощью непроверенных бросков:

 Builder(List::class.java) as Builder<List<Number>> Builder(List::class.java as Class<List<Number>>) 

Другой подход заключается в создании встроенной вспомогательной функции reified:

 inline fun <reified T : Any> Builder() = Builder(T::class.java) 

и использовать его следующим образом:

 Builder<List<Number>>() 

Решение заключается в использовании повторяющихся дженериков в паре с токенами суперкласса .

Пожалуйста, обратитесь к этому вопросу для объяснения метода. Конструкторы в Kotlin не поддерживают редифицированные дженерики, но вы можете использовать TypeReference описанный там, для написания фабричной фабричной функции, которая сохранит фактические общие параметры во время выполнения:

 inline <reified T: Any> fun builder(): Builder<T> { val type = object : TypeReference<T>() {}.type return Builder(type) } 

Затем внутри Builder вы можете проверить, является ли type ParameterizedType , и если это так, type.actualTypeArguments будет содержать фактические общие параметры.

Например, builder<List<Number>>() сохранит информацию о Number во время выполнения.

Ограничение этого подхода заключается в том, что вы не можете использовать не-reified generic в качестве параметра типа reified, потому что этот тип должен быть известен во время компиляции.