Kotlin 可见性

Kotlin 的可见性修饰符(Visiblity Modifiers)与 Java 有显著不同,而且设计上更符合现代编程习惯。

下面我为你彻底梳理 Kotlin 的可见性规则,并附上与 Java 的对比。

1. 四大修饰符速览表(最核心)

修饰符 顶层声明 (类/函数/属性) 类内部成员 (属性/方法/内部类) 说明
public 到处可见(默认) 到处可见(默认) 不写修饰符时默认就是这个。
private 仅当前文件内可见 仅当前类内部可见 比 Java 更严格(Java 的 private 是类级,Kotlin 顶层是文件级)。
protected (不允许使用) 当前类 + 子类可见 注意:同包下的子类可见,但同包下的非子类不可见。
internal 整个 Module 模块内可见 整个 Module 模块内可见 这是 Kotlin 独有的,Java 没有。

2. 关键细节深入解读

internal 是什么?(最重要区别)

internal 是 Kotlin 相比 Java 最大的进步。它解决了一个痛点:Java 的 package-private(默认修饰符)只能控制同一个包下可见,但包结构容易被绕过。

  • 作用域internal 限制在同一个编译模块(Module)内。
  • 模块定义:一个模块就是一个一起编译的工程,比如一个 Gradle 子项目、一个 Maven 模块,或者一个 Android Library。
  • 实际好处:如果你写了一个 SDK 库,想暴露给库内部所有包使用,但不暴露给外部 App 开发者,就用 internal。外部 App 完全无法访问它。

protected 的特殊限制

  • 在 Java 中,protected 允许同包下的其他类访问(哪怕不是子类)。
  • 在 Kotlin 中,protected 只允许子类访问,不允许同包下的非子类访问。这是为了更纯粹地遵循“保护继承”的语义。

③ 顶层声明中的 private

  • 在 Java 中,文件级 private 是不存在的(只有类级)。
  • 在 Kotlin 中,如果你在一个 .kt 文件里写 private fun helper(),那么只有这个文件里的代码能调用它,别的文件哪怕在同一个包下也看不见。

3. 与 Java 的对比(面试/迁移高频点)

场景 Java Kotlin
默认修饰符 default(包级私有) public(公开)
包级私有 支持(默认) 不支持(改用 internal 代替)
文件级私有 不支持 支持(private 顶层声明)
内部类访问外部 内部类默认持有外部类引用,可访问私有成员 内部类(Inner Class)不能直接访问外部类的 private 成员(需加 this@Outer 或改为 protected
同一文件多个类 default 可见 若无修饰符,public 完全可见

4. 实战代码示例

// ---- 文件1: Demo.kt ----
package com.example.demo

// 1. 顶层声明 (默认 public)
val version = "1.0"          // 全局可见

// 2. 顶层 private (仅当前文件可见)
private fun log(msg: String) { 
    println(msg) 
}

// 3. internal 类 (仅当前 Module 可见)
internal class InternalHelper {
    fun help() = "Helping"
}

// 4. public 类 (默认)
class User {
    // 5. private 属性 (仅类内部)
    private val id = 1
    
    // 6. protected 属性 (类 + 子类)
    protected val name = "Tom"
    
    // 7. internal 方法 (Module 内可见)
    internal fun printId() {
        println(id) 
        log("打印 ID") // 可以调用文件顶层 private 函数
    }
}

// 8. 子类访问 protected
class Admin : User() {
    fun show() {
        println(name) // ✅ 可以访问父类的 protected
        // println(id) // ❌ 不可以,id 是 private
    }
}

5. 最佳实践建议(避坑指南)

  1. 默认就用 public:Kotlin 的设计哲学就是“默认公开”,因为隐藏细节应该是有意识的行为。
  2. 库开发多用 internal:不要用 public 暴露你不想让外部调用的 API,否则用户会在 IDE 提示里看到一堆杂音。用 internal 既能共享代码,又能保持 SDK 接口干净。
  3. 慎用 protected 在顶层:记住顶层声明(文件级)写 protected 是编译报错的,因为文件没有“子类”概念。
  4. Java 调用 Kotlin 的注意internal 在 Java 眼中会变成 public(因为 JVM 没有模块概念),所以编译后 Kotlin 会进行名字修饰(Name Mangling),Java 代码虽然能看见,但调用起来很别扭(需要加后缀),这实际上阻止了 Java 直接调用。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容