проблема с параметром типа параметра

IntelliJ бросает на меня следующую ошибку, но, насколько я могу судить, проблем нет.

Минимальный пример

import org.springframework.jdbc.core.JdbcTemplate // ... var jdbcTemplate: JdbcTemplate? = null // ... relying on dependency injection from Spring if (jdbcTemplate == null) { throw RuntimeException("jdbcTemplate not injected correctly") } jdbcTemplate.execute("DROP TABLE customers IF EXISTS") 

Снимок экрана с ошибкой компилятора

Функция имеет три реализации. Один из них принимает String . Строка – это то, что я даю ей. Так что же?

Я пытался:

  • Недействительный кэш и перезапуск IntelloJ
  • Создание через ./gradlew build

+

 :compileKotlin e: /home/ruben/workspace/campingmanager/src/main/kotlin/hello/Application.kt: (27, 22): None of the following functions can be called with the arguments supplied: public open fun execute(sql: String!): Unit defined in org.springframework.jdbc.core.JdbcTemplate public open fun <T : Any!> execute(action: ConnectionCallback<(???..???)>!): (???..???) defined in org.springframework.jdbc.core.JdbcTemplate public open fun <T : Any!> execute(action: StatementCallback<(???..???)>!): (???..???) defined in org.springframework.jdbc.core.JdbcTemplate e: /home/ruben/workspace/campingmanager/src/main/kotlin/hello/Application.kt: (28, 22): None of the following functions can be called with the arguments supplied: public open fun execute(sql: String!): Unit defined in org.springframework.jdbc.core.JdbcTemplate public open fun <T : Any!> execute(action: ConnectionCallback<(???..???)>!): (???..???) defined in org.springframework.jdbc.core.JdbcTemplate public open fun <T : Any!> execute(action: StatementCallback<(???..???)>!): (???..???) defined in org.springframework.jdbc.core.JdbcTemplate :compileKotlin FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':compileKotlin'. > Compilation error. See log for more details * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. BUILD FAILED Total time: 8.113 secs 
  • Получение последней версии Kotlin 1.0.2-1

Kotlin версия : org.jetbrains.kotlin: kotlin-stdlib: 1.0.2

Версия плагина Kotlin : 1.0.2-1-release-IJ145-20

Версия IntelliJ : 2016.1.3

Проблема здесь в jdbcTemplate – она ​​может быть нулевой, поскольку она может быть изменена из другого потока. Чтобы исправить ошибку компиляции, вы должны заменить свой вызов на это: jdbcTemplate!!.execute("DROP TABLE customers IF EXISTS") .

О непонятном сообщении об ошибке есть проблема: KT-11119 .

Также может быть полезно использовать lateinit для этого случая. (дополнительную информацию см. в документации ).

Проверка с !! уродливый, вместо этого я предлагаю эти два подхода.

Используйте lateinit который специально добавлен для каркасов DI

 class Database { @Autowired private lateinit var jdbcTemplate: JdbcTemplate; fun initCustomerDatabase() { jdbcTemplate.execute("DROP TABLE customers IF EXISTS") } } 

Минусы: дополнительная проверка времени выполнения при каждом вызове на jdbcTemplate . Минусы: jdbcTemplate .

Использовать инъекцию конструктора:

 class Database @Autowired constructor(val jdbcTemplate: JdbcTemplate) { fun initCustomerDatabase() { jdbcTemplate.execute("DROP TABLE customers IF EXISTS") } } 

Плюсы: jdbcTemplate immutable Плюсы: Нет проверок времени выполнения.

Весной 4.3 вы можете написать следующий код даже без @Autowired constructor , например:

 class Database(val jdbcTemplate: JdbcTemplate) { fun initCustomerDatabase() { jdbcTemplate.execute("DROP TABLE customers IF EXISTS") } } 

Лично я использую инъекцию конструктора, потому что это очень полезно для тестирования.