函数参数类型匹配问题

时间:2016-06-30 09:49:27

标签: types kotlin

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")

Screen shot of compiler error

该功能有三个实现。其中一个接受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

2 个答案:

答案 0 :(得分:2)

这里的问题在jdbcTemplate - 它可以为null,因为它可以从其他线程更改。 要修复编译错误,您应该将对此的调用替换为: jdbcTemplate!!.execute("DROP TABLE customers IF EXISTS")

关于不明确的错误消息,存在问题:KT-11119

对于这种情况,使用lateinit也是一个好主意。 (有关详细信息,请参阅documentation。)

答案 1 :(得分:0)

检查!!丑陋,我建议采用这两种方法。

使用专为DI框架添加的lateinit

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不可变 优点:没有运行时检查。

在4.3版本中,即使没有@Autowired constructor,您也可以编写以下代码,例如:

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

我个人使用构造函数注入,因为它对测试非常有用。