Kotlin 内部类和嵌套类

Kotlin 中没有直接的「内部类」关键字 ,而是通过嵌套类标记为 inner 的嵌套类(内部类) 区分,这是和 Java 最大的不同,核心区别:是否持有外部类的引用


一、核心定义(一句话记住)

类型 关键字 持有外部类引用? 访问外部类成员 使用场景
嵌套类 无(直接写在类里) ❌ 不持有 只能访问外部类静态成员(companion 里的) 独立工具类、和外部类无依赖
内部类 inner 关键字 ✅ 持有 可以访问外部类所有成员(包括私有) 需要依赖外部类数据

二、代码示例(最直观)

1. 嵌套类(默认,不加 inner)

kotlin 复制代码
class Outer {
    private val outerVal = "外部类私有成员"
    companion object {
        const val staticVal = "外部类静态常量"
    }

    // 嵌套类(默认)
    class Nested {
        fun test() {
            // 错误!无法访问外部类普通成员(不持有引用)
            // println(outerVal)
            
            // 正确!可以访问静态成员
            println(staticVal)
        }
    }
}

// 调用方式:直接 外部类.嵌套类
fun main() {
    Outer.Nested().test()
}

2. 内部类(加 inner 关键字)

kotlin 复制代码
class Outer {
    private val outerVal = "外部类私有成员"

    // 内部类(必须加 inner)
    inner class Inner {
        fun test() {
            // 正确!可以访问外部类所有成员
            println(outerVal)
            // 显式引用外部类:this@Outer
            println(this@Outer.outerVal)
        }
    }
}

// 调用方式:必须先创建外部类对象
fun main() {
    Outer().Inner().test()
}

三、关键区别详解

1. 引用关系(最重要)

  • 嵌套类 :相当于 Java 的 static 内部类,完全独立,不持有外部类对象,内存上无关联。
  • 内部类 :相当于 Java 的普通内部类,强依赖外部类,必须依附外部类对象存在。

2. 创建方式不同

  • 嵌套类:外部类.嵌套类()
  • 内部类:外部类对象().内部类()

3. 访问权限不同

  • 嵌套类:只能访问外部类的静态成员(companion object 中)。
  • 内部类:可以访问外部类所有成员(private、protected、public 都可以)。

4. 内存泄漏风险

  • 嵌套类:无内存泄漏风险(无引用)。
  • 内部类:有内存泄漏风险(持有外部类引用,比如在 Android 中使用不当会导致 Activity 无法回收)。

四、和 Java 对比(快速对照)

Kotlin Java
嵌套类(class) 静态内部类(static class)
内部类(inner class) 普通内部类(class)

五、使用建议

  1. 优先用嵌套类:如果类不需要访问外部成员,一定用嵌套类(安全、无内存泄漏)。
  2. 内部类慎用 :只有必须依赖外部类数据时才用 inner
  3. 内部类中访问外部类:用 this@外部类名 区分(避免同名变量冲突)。

总结

  1. 不加 inner = 嵌套类:独立、无外部引用、只能访问静态成员、直接创建。
  2. 加 inner = 内部类:依赖外部类、持有引用、可访问所有成员、必须依附外部对象创建。
  3. 核心口诀:嵌套无引用,内部靠外部
相关推荐
昵称暂无12 小时前
低代码平台深度测评:OutSystems vs Mendix谁更胜一筹
开发语言·低代码
We་ct2 小时前
JS手撕:函数进阶 & 设计模式解析
开发语言·前端·javascript·设计模式·面试·前端框架
宸津-代码粉碎机2 小时前
Spring Boot 4.0 实战技巧全解析
java·大数据·spring boot·后端·python
Makoto_Kimur2 小时前
Java Scanner 的 ACM 常用输入模板
java·数据结构·算法
0xDevNull2 小时前
Spring 核心教程:@Component vs @Bean 深度解析
java·后端
Michelle80232 小时前
R语言 for循环
开发语言·r语言
小碗羊肉2 小时前
【从零开始学Java | 第三十二篇】方法引用(Method Reference)
java·开发语言
玖釉-2 小时前
C++ 硬核剖析:if 语句中的“双竖杠” || 到底怎么运行的?
开发语言·c++
满满和米兜3 小时前
【Java基础】- 集合-HashSet与TreeSet
java·开发语言·算法