1

I'm calling a Spring method from Kotlin and Spring provides 2 signatures, one that takes 2 args (the second being varargs) and one that takes 3 args.

I want to call the 3-arg method, but I can't figure out how to match the types - it keeps calling the 2-arg version with the varargs slurping the values.

Here are the method signatures (I want to call the first, but it keeps calling the second):

@Override
public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException {
    return update(sql, newArgTypePreparedStatementSetter(args, argTypes));
}

@Override
public int update(String sql, @Nullable Object... args) throws DataAccessException {
    return update(sql, newArgPreparedStatementSetter(args));
}

Here is my Kotlin code:

var sql = "INSERT INTO \"$sourceTable\" ($insertList) VALUES ($valueList)"
val p: Array<Any?> = params.toTypedArray()
val c: Array<Int> = columnTypes.toTypedArray()
targetJdbcTemplate.update(sql, p, c)

Clearly, something is going wrong and Array does not map to Object[], because my debugger shows me that I am calling the second method here, not the first.

How can I make Kotlin understand which method I want? How do I map Array<Any?> Array<Int> to Object[] and Int[] so the compiler will understand?

blacktide
  • 10,654
  • 8
  • 33
  • 53
mikeb
  • 10,578
  • 7
  • 62
  • 120
  • 3
    In Kotlin `Array` is a `Integer[]` under the hood, and `IntArray` is an `int[]` (more info [here](https://stackoverflow.com/a/45094889/2446208)). Not sure if it will help in this case but does changing `c` to [`c.toIntArray()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-int-array.html#tointarray) on the last line solve the problem? – blacktide Jan 26 '23 at 16:44
  • Put that in an answer so I can mark it correct - and thanks! – mikeb Jan 26 '23 at 17:02
  • Glad it worked out! Just posted it as an answer. – blacktide Jan 26 '23 at 23:48

2 Answers2

2

In Kotlin Array<Int> is a Integer[] under the hood, and IntArray is an int[] (see here).

To resolve the issue, you can change c to c.toIntArray() on the last line:

targetJdbcTemplate.update(sql, p, c.toIntArray())
blacktide
  • 10,654
  • 8
  • 33
  • 53
1

When doing Kotlin -> Java interrop, Kotlin has specific Array types to help deal with this kind of ambiguous Type.

In this case you will want to use IntArray in Kotlin to map to the proper type in Java

There are a number of other Primitive array types such as: ByteArray, ShortArray, IntArray

Reference: https://kotlinlang.org/docs/arrays.html#primitive-type-arrays

Benjamin Charais
  • 1,248
  • 8
  • 17