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. 核心口诀:嵌套无引用,内部靠外部
相关推荐
云烟成雨TD18 小时前
Spring AI Alibaba 1.x 系列【69】Token 用量统计
java·人工智能·spring
JAVA96518 小时前
JAVA面试-并发篇 03-使用synchronized doublecheck实现单例有什么坑
java·单例模式·面试
在繁华处18 小时前
Java从零到熟练(四):面向对象基础
java·开发语言
Unbelievabletobe18 小时前
解决了股票api接口盘后数据更新慢的问题
大数据·开发语言·python
不会C语言的男孩19 小时前
C++ Primer 第2章:变量和基本类型
开发语言·c++
小江的记录本19 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
在繁华处20 小时前
Java从零到熟练(三):流程控制
java·开发语言·python
唐青枫20 小时前
Java Optional 实战指南:优雅处理空值与链式转换
java
一起学开源20 小时前
一文读懂 ReAct 范式:让 AI Agent 真正学会“思考+行动“
java·javascript·react.js·ecmascript·react·alibaba·智能体开发
云泽80820 小时前
C++ 可调用对象通关指南:深度解析 Lambda 表达式、function 包装器与 bind 绑定器
开发语言·c++·算法