Я уменьшил свою проблему до минимальной демонстрации:
interface Property<T : Comparable<T>> fun <T : Comparable<T>> parsePropertyValue(property: Property<T>, value: String): T = TODO() fun test() { val property: Property<*> = TODO() val value = parsePropertyValue(property, "test") }
Вызов parsePropertyValue
не компилируется с сообщением об ошибке «Невозможно указать параметр типа T». Эквивалентный код Java компилируется без проблем:
interface JavaProperty<T extends Comparable<T>> { } class Test { public static void main(String[] args) { JavaProperty<?> property = null; Comparable<?> value = parsePropertyValue(property, "test") } private static <T extends Comparable<T>> T parsePropertyValue(JavaProperty<T> property, String value) { return null; } }
Как можно добиться чего-то подобного в Котлине? Обратите внимание, что интерфейс Property
в этом примере – из внешней библиотеки, и я не могу его изменить.
Согласно запросу, немного больший пример:
interface Property<T : Comparable<T>> { fun parseValue(value: String): T } interface PropertyStore { fun <T : Comparable<T>> setValue(property: Property<T>, value: T) fun <T : Comparable<T>> getValue(property: Property<T>): T } fun main() { val property: Property<*> = TODO() val unparsedValue: String = TODO() val propertyStore: PropertyStore = TODO() } fun <T : Comparable<T>> parseAndApplyValue(propertyStore: PropertyStore, property: Property<T>, unparsedValue: String) { val parsedValue: T = property.parseValue(unparsedValue) propertyStore.setValue(property, parsedValue) }
Причина, по которой он не компилируется, заключается в том, что Property
должно быть параметризовано чем-то, что является Comparable
и *
is not.
Любой шанс, который вы можете изменить
val property: Property<*> = TODO()
в
val property: Property<Int> = TODO()
или что-то еще, что Comparable
? Это приведет к компиляции кода.
IntelliJ IDEA подсказывал вам ответ, хотя и не в том месте:
Обратите внимание на серое подчеркивание? Это проверка, в которой вам предлагается добавить модификатор «in» variation:
После изменения кода на interface Property<in T : Comparable<T>>
все скомпилируется.
Вы можете узнать больше о различиях здесь: http://kotlinlang.org/docs/reference/generics.html