Могу ли я передать информацию о типе, чтобы упростить это?

У меня много таких кодов, это все равно, кроме типа PositionJson , это может быть AnotherJson или FooJson или BarJson

Есть ли какой-то способ, который я могу исключить весь этот код в одну функцию, чтобы как-то передать в нее тип? Так что у меня нет нескольких из этих больших блоков почти одинакового кода, замусоривающих мой класс?

Я не уверен, что это возможно или нет, просто подумал, что я спрошу, потому что было бы неплохо сделать …

  /** * @return the _open_ [PositionJson]s */ val positions: Array<PositionJson>? @Throws(AccountsAPIException::class) get() { val service = constructServiceURL(POSITIONS, null, true) try { val messageJson = mapper.readValue<MessageJson<Array<PositionJson>>>( callURL(service), object: TypeReference<MessageJson<Array<PositionJson>>>() { }) val error = messageJson.error if (error != null) throw AccountsAPIException(error.errorCode, error.description) return messageJson.data } catch (e: Exception) { throw AccountsAPIException(e) } } 

Вы можете делать то, что хотите, с помощью дженериков. Однако для использования дженериков нам сначала нужно извлечь этот гигантский блок кода в метод:

 val positions: Array<PositionJson>? get() = getPositions() fun getPositions(): Array<PositionJson>? { ... } 

Мы не решили проблему, но теперь мы в состоянии решить ее, создав getPositions generic (обратите внимание, что я также переименовал функцию):

 val positions: Array<PositionJson> get() = getArrayOf<PositionJson>() // thanks to type inference I can omit the type on getArrayOf if desired: val positions: Array<PositionJson> get() = getArrayOf() fun <T> getArrayOf(): Array<T>? { val service = constructServiceURL(POSITIONS, null, true) try { val messageJson = mapper.readValue<MessageJson<Array<T>>>( callURL(service), object: TypeReference<MessageJson<Array<T>>>() { }) val error = messageJson.error if (error != null) throw AccountsAPIException(error.errorCode, error.description) return messageJson.data } catch (e: Exception) { throw AccountsAPIException(e) } } 

Отлично! Кроме того, это не будет скомпилировано благодаря стиранию типа. Но мы можем исправить это, сделав функцию inline и сделав параметр типа reified :

 inline fun <reified T: Any> getArrayOf(): Array<T>? { ... } 

И это должно сделать это. Теперь вы можете повторно использовать эту функцию по мере необходимости:

 val positions: Array<PositionJson>? get() = getArrayOf() val persons: Array<PersonJson>? get() = getArrayOf() val bananas: Array<BananaJson>? get() = getArrayOf() inline fun <reified T: Any> getArrayOf(): Array<T>? { val service = constructServiceURL(POSITIONS, null, true) try { val messageJson = mapper.readValue<MessageJson<Array<T>>>( callURL(service), object: TypeReference<MessageJson<Array<T>>>() { }) val error = messageJson.error if (error != null) throw AccountsAPIException(error.errorCode, error.description) return messageJson.data } catch (e: Exception) { throw AccountsAPIException(e) } } 

Последнее: обратите внимание, что во всех моих примерах я использовал свойство getters ( get() = ... ), как в вашем исходном коде. Тем не менее, я сильно подозреваю, что вы НЕ хотите использовать геттер. Getters будет вызываться каждый раз, когда кто-то обращается к вашей собственности, что в данном случае означает, что каждый раз, когда кто-то читает свойство positions вы вызываете constructServiceURL и вызываете вызов службы и т. Д. Если вы хотите, чтобы этот код происходил только один раз, тогда вы должны просто вызовите getArrayOf() один раз и присвойте результат вашему свойству:

 val positions: Array<PositionJson>? = getArrayOf() // this syntax would also work: val positions = getArrayOf<PositionJson>() 
Intereting Posts
Коллекции Kotlin бросают ClassNotFoundException на Android Уведомлять наблюдателя, когда элемент добавлен в список LiveData Как назвать assertEquals с Double Epsilon / Precision в Котлине? В чем разница между «const» и «val»? Как вызвать суперкласс класса super из внутреннего класса в Котлине? Как развернуть приложение Kotlin в Heroku? Как добавить поддержку градиента для проекта TestNG Kotlin? RuntimeException: не удалось создать экземпляр активности ComponentInfo … ClassNotFoundException Kotlin – Список в списке фильтрации Простой способ узнать, является ли класс анонимным / объектом и получить конкретное имя класса из экземпляра в Котлине Преобразование html-строки в pdf или изображение в Android параметр vararg в лямбда Escape зарезервированные слова в импорте Преобразование императивной функции root в функциональный стиль в kotlin Объявление байта в Kotlin делает ошибку времени компиляции «Целочисленный литерал не соответствует ожидаемому типу Byte»