Kotlin内联函数是编译期将函数体直接插入调用处的优化机制,用于消除高阶函数调用开销、避免Lambda对象创建、支持reified泛型,并协同JVM JIT实现更高性能。

方法内联是 JVM 对短小对象行为实现执行加速最直接、最底层的机制之一。它不依赖对象本身是否“轻量”,而是聚焦于调用上下文——只要方法体足够简单、被频繁调用,JVM 就可能将其代码“摊平”到调用处,从而绕过对象创建、栈帧压入、字段访问跳转等开销。理解这一点,就能抓住短小对象加速的本质:不是对象快,而是“不把它当对象用”。
短小对象常出现在 getter/setter、包装类操作、工具函数中
比如一个 User 实体的 getName() 方法,或 Optional.ofNullable(x).orElse("") 中的链式调用,表面看是对象行为,实际逻辑极简。JVM 会优先对这类方法触发内联:
- getter/setter 默认被 C2 编译器内联(无需
final或private,只要未被重写) -
Integer.valueOf(int)、Boolean.valueOf(boolean)等装箱方法,在热点路径下大概率被内联,避免创建新对象 - 像
Objects.requireNonNull(obj)这类校验方法,内联后只剩一条判空指令,完全消除方法边界
内联让对象访问退化为字段直读,跳过对象生命周期管理
以 user.getName() 为例,未内联时需:查虚表 → 定位方法入口 → 压栈 → 执行 → 弹栈 → 返回;内联后,编译器可进一步结合逃逸分析,发现 user 未逃逸,进而将整个调用优化为直接读取 user.name 字段地址——连对象头访问都可能被省略。这正是短小对象“变快”的关键:它不再作为独立运行时实体参与调度,而成为调用者代码的一部分。
实战中验证内联效果的三个可靠方式
光靠理论不够,需用数据确认 JVM 是否真正内联了目标方法:
- 加
-XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining启动 JVM,观察日志中是否出现inline (hot)或did not inline (too big)等明确提示 - 用
javap -c反编译字节码,检查调用点是否还保留invokevirtual指令;若已消失,说明 Kotlin 的inline或 JVM JIT 已完成内联 - 在 JMH 基准测试中对比:同一逻辑封装为普通函数 vs
inline函数,典型提升在 15%–40%,尤其在循环体内高频调用时更明显
Kotlin 内联函数是对 JVM 内联的主动协同
JVM 的 JIT 内联是运行时决策,有延迟且不可控;而 Kotlin 的 inline 是编译期强制展开,特别适合短小高阶函数场景:
- 把
run { ... }、also { ... }内联后,lambda 不再生成FunctionN实例,彻底规避对象分配 - 配合
reified类型参数,能在字节码中直接写出具体类名,绕过泛型擦除带来的反射开销 - 注意:仅对函数体小(通常

















