Kotlin/Java互操作性中,Integer! 不会自动转换成Int?

移动开发 2026-07-09

我有以下代码:

    fun extractWorkspaceId (token : String) : Int? = extractClaim(token) { it.get("ws", Integer::class.java) }

extractClaim 被定义为类型 fun <T> extractClaim (token : String, resolver : (Claims) -> T) : T,其中 Claims 是一个包含方法 T <T> get(String, Class<T>) 的Java类。编译时我得到如下错误:

JwtTokenService.kt:31:76 Return type mismatch: expected 'Int?', actual 'Integer!'.

显然 Integer 应该会自动转换为 Int,那么在这种情况下,为什么 Integer! 没有自动转换为 Int??在表达式末尾添加 as Int? 可以正常工作,但为什么不会自动发生?

解决方案

从来就没有 java.lang.Integerkotlin.Int 之间的隐式转换。这是设计上的要求:数字类型必须彼此显式地进行转换,而不能隐式进行。

数值类型并非互为子类型。Kotlin要求显式转换,以避免悄无声息的数据丢失和意外行为。

fun f(javaInteger: Integer) {
    val kotlinInt: Int = javaInteger // does not compile!
}

你可能在想的行为是,涉及 Integer 的Java声明被导入到Kotlin中,作为 Int!(或 Int?)。这确实是对的,但在你的情况,Java声明并不涉及任何 Integer

// this is a totally generic method! No Integer involved at all!
<T> T get(String s, Class<T> c)

get 只是在导入到Kotlin时几乎没有变动:

// from Kotlin's perspective:
fun <T> get(s: String!, c: Class<T!>!): T!

类型 Integer 只有在你调用 get 时才会出现,而 get 位于Kotlin代码中,因此就适用Kotlin的规则。

除了 as Int?,你还可以

  • 在末尾调用 .toInt()Integer 转换为 Int,或
  • 传入 Int::class.javaObjectType 代替 Integer::class.java。这在Java中的效果与 Integer.class 相同,但在Kotlin中的类型是 Class<Int>

旁注:这种情况与例如 java.util.ArrayListkotlin.collections.ArrayList 不同。Kotlin的 ArrayList 只是Java的 ArrayList 的一个类型别名,因此可以在它们之间隐式“转换”。

fun f(javaList: java.util.ArrayList<String>) {
    // OK!
    val kotlinList: kotlin.collections.ArrayList<String> = javaList
}

其实并没有进行任何“转换”——它们只是同一类型的两种不同名称。

java.lang.Integerkotlin.Int 则是不同的类型。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章