如何在不同的模块中隐藏Java中Kotlin内部类的可见性



我正在Kotlin开发Android库。我保留了一些类的访问修饰符作为internal。内部类仅在Kotlin的库模块中可见。如果我在应用程序中实现了这个库,那么它就根本看不见了。

但是,当从Java代码访问该库时,问题就来了。如果我创建了.java文件并键入库的internal类的名称,那么IDE就是建议名称,并且它被解析和编译而没有任何错误。

例如

库模块:

internal class LibClass {
// Fields and Methods
}

DemoApp模块中实现上述库后:

应用程序模块

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

这就是问题所在。如何从Java中保护该类?

谢谢!

我看到您有一个带有内部修饰符的类,它不能在kotlin类中实例化,但可以在Java文件中实例化。如果它是一个独立的类,您可以将其构造函数设为私有的,并允许使用静态方法(Companion对象(进行实例化。

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

用空格或特殊符号对internal class@JvmName的每个公共方法进行注释,从而在Java中产生语法错误

例如

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的每个公共方法,通过这些方法Java无法访问公共方法

例如

internal class LibClass {
@JvmSynthetic
fun foo() {}
@JvmSynthetic
fun bar() {}
}

注:

本文对此进行了详细解释。

如果您想隐藏类的可见性,而不是每个函数或字段,可以在类的顶部使用@file:JvmSynthetic

例如

@file:JvmSynthetic
package  com.example.app
internal class LibClass {
var count: Int = 0
internal fun exampleFun() {

}
}

最新更新