为何 Kotlin internal 修饰的类或者方法在 Java 中可以被调用

1,303 阅读1分钟

问题

首先了解下 Kotlin 的 internal 修饰符,它用于限制类、函数或属性的可见性,只在同一个模块中可见。类似的可见性修饰符在 Java 里是没有的。

现在的问题是我们在 moduleA 中定义一个 internal 修饰的 ATest 类,正常来说在 moduleB 中我们应该是找不到 ATest 的。出现的情况是 moduleB 中如果创建一个 BTest.java 类去调用 ATest 是可以调用。只是提示 Usage of Kotlin internal declaration from different module,但是可以编译并且正常运行的。moduleB 中 Kotlin 类无法调用到 ATest 的符合情况。测试代码如下:

//moduleA 中的 ATest 类
internal class ATest {

}
//moduleB 中
public class BTest {
    public void test(){
        //提示 Usage of Kotlin internal declaration from different module
        new ATest();
    }
}

解决方法

问题的原因是 Java 中没有 internal 类似的修饰符,所以 Kotlin 的 internal 修饰的内容变成 public 了。以下给出各种场景的解决方案。

  1. 如果 internal 修饰的是类,则可以如下下修改
internal class `-ATest` {

}

Kotlin 可以使用``把一个不合法的标识符强行合法化,这在 Java 里是无法识别的。

  1. 如果 internal 修饰的是方法,则可以如下修改
class ATest {
    @JvmName("-test")
    internal fun test(){

    }
}

使用 @JvmName 修改方法的名称为 -test,这样 Java 就调用不到了。

总结

这个问题是在看 ViewPump 这个开源项目遇到的,发现它使用了这种解决方式。感兴趣的朋友也可以了解下这个项目。