从 Java(和 Kotlin)隐藏 Kotlin 对象的 INSTANCE 字段

Eri*_*rik 6 java singleton interop kotlin kotlin-java-interop

简短的问题

我可以将 Kotlin 对象INSTANCE(对于 Java 互操作)的可见性修改为internal或更低吗?

长问题

我正在编写一个库,我想要一个用 Kotlin 编写的API 文件/类,它公开一个可以从 Java 或 Kotlin 调用的函数,如下所示:

科特林:

API.function()
Run Code Online (Sandbox Code Playgroud)

爪哇:

API.function()
Run Code Online (Sandbox Code Playgroud)

我可以通过这样写来实现这一点:

科特林:

object API {
    @JvmStatic
    fun function() = TODO()
}
Run Code Online (Sandbox Code Playgroud)

不过,现在我也可以这样做:

爪哇:

API.function();
Run Code Online (Sandbox Code Playgroud)

为了简单起见,我想阻止这种访问,以INSTANCE将 API 界面保持在最低限度。

我可以将可见性修改为INSTANCEinternal更低吗?

这可能是不可能的,因为对API(来自 Kotlin)的任何调用都会返回对象的实例,并且该实例也应该被隐藏才能实现这一点。不过,我很好奇它是否没有受到重大黑客攻击。

使用 Java 的解决方案是用APIJava 编写:

object API {
    @JvmStatic
    fun function() = TODO()
}
Run Code Online (Sandbox Code Playgroud)

但是,我正在寻找用 Kotlin 编写的解决方案。

Lin*_*ica 6

我能想到的最接近的是这样的:

API.kt在包中创建一个文件com.example.api。将您的函数直接添加到该文件中,如下所示:

@file:JvmName("API")

package com.example.api

fun function() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

科特林:

您可以在需要使用 api 的任何地方导入该函数:

import com.example.api.function
Run Code Online (Sandbox Code Playgroud)

虽然你不能API.function再使用你的语法了。

爪哇:

生成的类看起来像这样(没有单例,只有静态方法,但没有私有构造函数):

 public final class API {
     public static final void function() {
         // ...
     }
 }
Run Code Online (Sandbox Code Playgroud)

然后你可以这样称呼它API.function();


通过指定,@file:JvmName("API")您可以指示 kotlin 命名创建的类API