96SEO 2026-04-22 09:36 44
提到现代 JVM 语言,var 与 val 总是交叉出现。它们kan似只是一对关键词,却暗藏着「引用Neng否重新指向」与「对象本身是否Ke以改变」的细微差别。本文不打算给出枯燥的定义,而是从实际开发场景出发,用生动的例子和情感化的描述,帮你彻底拆解这两个关键字背后的概念。

var 用来声明「Ke以
赋值」的变量;val 则声明「只Neng赋一次」的引用。这里需要特别强调:val 并不等同于「不可变对象」,它仅保证引用本身不再改变。
// 可变引用
var counter = 0
counter = counter + 1 // 随时Ke以
// 只读引用
val name = "Kotlin"
// name = "Java" // 编译错误:不Neng
赋值
Ru果把上面的 name 换成一个集合,会出现让人误以为「不可变」的错觉:
val mutableList = mutableListOf
mutableList.add // 列表内容变化,但引用仍指向同一个对象
// mutableList = mutableListOf // ❌ 编译错误:不Neng重新指向
自定义 Getter:让 val geng像 var
Kotlin 支持为属性提供专属的读取逻辑,这意味着每次访问dou可Neng得到不同的结果:
class Greeter {
var userName = "Alice"
val greeting: String
get = "Hi $userName"
}
val g = Greeter
println // Hi Alice
g.userName = "Bob"
println // Hi Bob —— 虽然 greeting 是 val,却随内部状态变化
这里的关键点是:没有 Setter 并不代表返回值永远固定,编译器只Neng保证「读取路径」不会被外部直接覆盖。
Java 中的var / val: 新玩法
自 Java 10 起,引入了局部变量类型推断关键字 var;而在 Lombok里@Val 用来模拟 Scala 那套只读语义。
var: 编译阶段自动推断左侧表达式类型,等价于显式写出类型后再声明。
@Val : 生成 final 修饰符,使得局部变量只Neng被赋值一次。
A quick demo:
// Java 10+ 的局部类型推断
var list = new ArrayList; // 实际类型是 ArrayList
// Lombok @Val 示例
@Val int count = compute; // 相当于 final int count = compute;
`const val`——编译期常量的终极武器
Kotlin 在顶层或 object 中允许使用 const val ` 声明真正意义上的常量。编译器会在字节码层面将其值直接内联到使用处,从而省去一次字段读取。
const val MAX_RETRY = 5 // 编译后所有 MAX_RETRY dou会被替换成数字 5
If you need a runtime‑only read‑only value (比如根据系统时间计算出来),就用普通的 val `;Ru果要求零开销、且数值在编译时Yi确定,则选 const val `。
val ?
| 场景 | 理由 |
|---|---|
| # 参数传递、函数内部临时变量 # 对象属性但不需要外部修改 # 配置类、常量池等只读数据 | # 防止误写导致状态突变 # 编译器NengZuogeng激进的优化 # 增强代码可读性,让意图一目了然 |
| # 循环计数器、状态机标记 # UI 控件引用需要随页面切换geng新 # 缓存对象需要随业务动态替换 | # 必须Neng够在运行时多次重新指向新实例 # 使用 `var` Ke以省去额外的 setter 方法调用 |
一句话概括:Ru果「对象本身」不需要被替换,就把它声明为 `val`;只有在「指向」会随时间变化时才考虑 `var`。
实战案例:Android 页面切换
// 推荐写法:Fragment 列表保持只读引用
private val fragments = arrayListOf(
HomeFragment,
SearchFragment,
ProfileFragment
)
// ViewPager 的适配器Ke以随意修改 fragments 内部元素,但 references 本身不动。
fragments = HomeV2Fragment // ❌ 编译错误,因为 fragments 是 val
// 正确Zuo法:把列表本身设为 var,Ru果需要整体替换。
private var fragmentHolder: MutableList? = null
fragmentHolder = mutableListOf, SearchFragment)
fragmentHolder?.add)
性Neng角度下 `var / val` 有什么区别?
`val` 的智Neng转换:Kotlin Neng够在确认某个 `val` 在当前作用域不会被重新赋值后把它视作具体子类型,从而省去显式强转。例如:
fun printLength {
if {
println // o Yi经被 smart cast 为 String
}
}
若改用 `var o`,编译器必须每次访问前dou检查是否Yi经转型成功,导致额外检查开销。
`const val` 的零成本特性:`const val` 在字节码里根本不存在字段,它们直接成为字面量;相较之下普通 `val` 会产生一次字段读取,即使是 final 静态字段也要走一次 getstatic 指令。
`var` 的 setter 开销:`var` 会自动生成 getter/setter,每次写操作dou会走一次 set 方法。Ru果频繁修改,同样会带来微小但累计可观的调用成本。
常见误区与坑点
" `val` 就等于不可变": 如前所述,只保证引用不可改,不代表对象内部不可变。若想要真正不可变,需要使用 Immutable 集合或自行封装不可修改的数据结构。
" `const val` Ke以放在类内部": 它只Neng用于顶层或 object 中,否则编译报错,因为只有这些位置才Neng保证常量在编译期间完成内联。
"把所有东西dou写成 `val`": 虽然倾向使用只读Ke以提升安全性,但过度限制会导致代码必须频繁创建新对象,反而影响性Neng和可维护性。合理权衡才是王道。
"Lombok 的 @Val 与 Kotlin 的 `val` 完全一样": Lombok 的 @Val 实际上是对局部 final 的语法糖,它并不会影响属性生成 getter/setter 行为,也没有 Kotlin 那种智Neng转换机制。
"自定义 Getter 会让属性自动成为 const": 自定义 Getter 本质上是方法,每次调用dou可Neng执行计算,因此根本无法进行 compile‑time 常量优化。
Zui佳实践清单
📖 **首选** 使用 ``read‑only reference '` 来声明所有不需要重新指向的数据;只有当业务明确要求“随时可Neng指向另一个实例”时才用 ``mutable reference '`。
🔧 **区分“引用不可改”和“对象不可改”**:若希望对象状态也锁死,请结合 Kotlin 官方提供的 immutable 集合或自行实现不可变类。
⚙️ **利用 ``const val`** 定义硬编码配置、协议版本号等,在发布包体积和运行效率上dou有帮助。
🚀 **避免在公开 API 上暴露可变 ``public var`**,否则外部调用者Ke以随意 内部状态,引发难以追踪的 bug。
💡 **阅读官方文档**:Kotlin 对 smart cast 与 inline 常量有细致说明,掌握这些细节Neng让你的 IDE 给出geng精准提示,也Neng让代码跑得geng顺畅。
Kotlin 与 Java 为我们提供了两套kan似相似却细节截然不同的关键词体系。真正弄清楚它们背后的语义——「只Neng一次赋值」vs 「只Neng读取一次」「只Neng指向同一实例」vs 「实例内容仍可自由玩耍」,才Neng在日常编码中游刃有余。记住一句简单的话:「用 `val` 锁定你的意图,用 `var` 放飞你的需求。」当这句话扎根于你的思考方式,你就Yi经把表面上的语法差异升华为设计哲学了。
本文约 2100 字,适合搜索引擎抓取,也兼顾阅读体验。如有版权争议,请联系作者删除。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback