1. 概述
在本文中,我们将对比 Java 和 Kotlin 中的默认访问修饰符行为。接着我们会介绍 Kotlin 中模块(module)的概念,最后展示如何在 Kotlin 中封装内部逻辑。
2. Java 中的 package-private
Java 中的默认访问修饰符(即无显式修饰符)允许同一包下的类访问该类的成员。这个修饰符无需关键字,是 Java 中类和成员的默认访问级别。
⚠️ 需要注意的是,这种修饰符并不能提供真正的封装。比如,只要新建一个类放在同一个包下,就可以访问 package-private 成员。这也是为什么 Kotlin 中没有直接对应的 package-private 修饰符的原因之一。
此外,如果希望一个类对外暴露,必须使用 public
。但一旦设为 public,就相当于对所有人开放了访问权限。
3. Kotlin 中的默认访问修饰符
Kotlin 中有以下几种可见性修饰符:
public
(默认)private
internal
protected
✅ Kotlin 默认使用 public
修饰符,其行为与 Java 类似:允许外部代码访问。
❌ 但 Kotlin 并没有直接对应 Java 的 package-private 的修饰符。
4. Kotlin 中的模块定义
在 Kotlin 中,模块(module)通常指的是:
一组一起被编译成一个 jar 文件的源码文件。
常见的模块包括:
- IntelliJ 中的 module
- Maven 项目
- Gradle 的 source set
- 使用 Ant 编译的一组文件
模块这个概念在理解 internal
修饰符时非常重要。
5. 使用 internal
封装内部逻辑
在 Java 中我们用 package-private 来限制访问范围,但在 Kotlin 中,**internal
是更优的替代方案**。
✅ internal
的作用是:仅在模块内可见。相比 package-private,它提供了更强的封装性。
主要优势包括:
- 不会暴露内部类或方法给外部模块
- 同一模块内任意包都可以访问
- 更适合用于封装库内部逻辑,对外不暴露
示例代码
我们定义一个 internal
类:
internal class InternalClass {
internal fun helloFromInternalFunction(): String {
return "Hello"
}
}
然后在另一个包中调用它(但仍在同一模块中):
fun whenCallInternalClass_thenItWorks() {
val internalClass = InternalClass()
assertThat(internalClass.helloFromInternalFunction()).isEqualTo("Hello")
}
✅ 虽然调用类在不同包中,但因为处于同一模块,所以可以访问 internal
方法。
6. 总结
本文对比了 Java 和 Kotlin 中默认访问修饰符的行为差异。我们还介绍了 Kotlin 中模块的概念,并展示了如何使用 internal
来封装内部逻辑。
如果你正在从 Java 迁移到 Kotlin,或者设计一个 Kotlin 库,建议使用 internal
替代 Java 的 package-private,以获得更好的封装性和模块级控制。
完整示例代码可在 GitHub 上查看。