如何从不同模块隐藏 Java 中 Kotlin 内部 class 的可见性?

How to hide visibility of Kotlin internal class in Java from different modules?

我正在研究我在 Kotlin 中开发的 Android 库。我将某些 classes 的访问修饰符保留为 internal。内部 classes 仅在 Kotlin 的库模块中可见。如果我在应用程序中实现该库,那么它根本不可见。

但是从 Java 代码访问该库时会出现问题。如果我创建 .java 文件并键入库的 internal class 的名称,那么 IDE 会建议名称,并且它会在没有任何错误的情况下得到解析和编译。

例如

库模块:

internal class LibClass {
    // Fields and Methods
}

DemoApp 模块中实现上述库后:

应用模块

科特林:
fun stuff() {
    val lib = LibClass() // Error.. Not resolving
}
Java:
public void stuff() {
    LibClass lib = new LibClass() // Successfully resolving and compiling
}

这就是问题所在。我怎样才能确保 class 来自 Java?

谢谢!

不是完美的解决方案,但我发现了两个 hacky 解决方案

用空格或特殊符号注释 internal class 的每个 public 方法 @JvmName,它会在 Java.[=27 中产生语法错误=]

例如

internal class LibClass {

    @JvmName(" ") // Blank Space will generate error in Java
    fun foo() {}

    @JvmName(" $#") // These characters will cause error in Java
    fun bar() {}
}

由于上述解决方案不适合管理大型项目或似乎不是很好的做法,因此以下解决方案可能会有所帮助。

通过 @JvmSynthetic 注释 internal class 的每个 public 方法,其中 Java 无法访问 public 方法。

例如

internal class LibClass {

    @JvmSynthetic
    fun foo() {}

    @JvmSynthetic
    fun bar() {}
}

注:

这在this article中有详细解释。

我看到你有 class with internal modifier 无法在 kotlin class 中实例化但可以在 Java 文件中实例化。 如果它是独立的 class,您可以将其构造函数设为私有并允许使用静态方法(Companion 对象)进行实例化。

如果您想隐藏 class 而不是每个函数或字段的可见性,您可以在 class.

之上使用 @file:JvmSynthetic

例如

@file:JvmSynthetic
package  com.example.app

internal class LibClass {
    var count: Int = 0

    internal fun exampleFun() {
        
    }
}