当前位置: 首页 > news >正文

java中final关键字的含义

在 Java 中,final 是一个关键字,用于声明不可变的实体。当 final 修饰字段(成员变量或静态变量)时,它赋予该字段一系列重要的语义和约束。


🔐 一、final 字段的核心特点

特点说明
一旦赋值,不可更改final 字段只能被赋值一次,之后不能再修改。
强制初始化必须在对象构造完成前完成初始化(构造器、初始化块、声明时)。
线程安全正确初始化的 final 字段具有“final field semantics”,保证多线程下可见性。
可用于常量通常与 static 结合,定义类级别的常量。
编译期优化如果 final 字段是编译时常量(如 final int x = 5;),编译器可内联其值。

🧩 二、final 字段的初始化规则

final 字段必须在以下之一中完成初始化,否则编译报错:

1. 声明时直接赋值(最常见)

public class Person {private final String name = "Alice";  // 声明时初始化private final int age = 25;
}

2. 实例初始化块(Instance Initializer Block)

public class Person {private final String name;{name = "Bob";  // 在初始化块中赋值}
}

3. 构造器(Constructor)中赋值

public class Person {private final String name;public Person(String name) {this.name = name;  // 构造器中赋值}
}

⚠️ 注意

  • 如果类有多个构造器,每个构造器都必须为 final 字段赋值
  • 不能在普通方法或后续代码中重新赋值。

📌 三、final 字段的类型差异

1. 基本类型(Primitive)

private final int value = 100;
// value = 200;  // ❌ 编译错误!
  • 值本身不可变。

2. 引用类型(Object Reference)

private final List<String> list = new ArrayList<>();// 合法操作:
list.add("hello");        // ✅ 可以修改对象内部状态
list.set(0, "world");     // ✅// list = new ArrayList<>();  // ❌ 编译错误!引用本身不能变

🔥 关键点
final 修饰的是引用本身,而不是对象的内容。
即:引用不可变,但对象可变

✅ 如果需要完全不可变,应使用不可变集合

private final List<String> list = List.of("a", "b"); // Java 9+

🧱 四、static final:定义常量

finalstatic 结合时,用于定义类级别的常量

public class Constants {public static final double PI = 3.14159;public static final String APP_NAME = "MyApp";public static final int MAX_RETRY = 3;
}

特点:

  • 属于类,不依赖实例。
  • 通常命名全大写(约定)。
  • 如果是编译时常量(值在编译期确定),编译器会内联(inline)其值。

⚠️ 注意:如果 static final 字段的值在运行时确定(如调用方法),则不会内联。


🧪 五、final 字段与线程安全

Java 内存模型(JMM)对 final 字段有特殊保证:

“Final Field Semantics”
一旦对象构造完成,其他线程看到的 final 字段的值,一定是构造器中设置的值,不会看到未初始化或中间状态

示例:

public class ImmutablePoint {private final int x;private final int y;public ImmutablePoint(int x, int y) {this.x = x;this.y = y;}// 安全发布后,x 和 y 的值对所有线程可见
}

✅ 这是构建不可变对象(Immutable Object) 的基础,广泛用于并发编程。


🚫 六、不允许的操作(编译错误)

public class Example {private final int value;public Example() {// value = 10;  // ✅ 正确:构造器中赋值}public void setValue() {// value = 20;  // ❌ 错误:不能在方法中赋值}{// value = 5;   // ✅ 可以在初始化块中赋值}
}

✅ 七、最佳实践

场景推荐用法
定义常量public static final TYPE NAME = value;
构建不可变类所有字段 private final,无 setter
依赖注入final 字段 + 构造器注入,确保依赖不为空
避免魔法值final 常量替代硬编码数字/字符串

示例:不可变类

public final class Person {private final String name;private final int age;public Person(String name, int age) {this.name = name;this.age = age;}// 只有 getter,没有 setterpublic String getName() { return name; }public int getAge() { return age; }
}

✅ 总结

final 字段的核心特点:

  1. 只赋值一次:必须在声明、初始化块或构造器中初始化。
  2. 不可更改:一旦赋值,不能再修改(引用或基本类型值)。
  3. 线程安全:正确初始化后,多线程下可见性有保障。
  4. 引用 vs 对象final 保证引用不变,不保证对象内容不变。
  5. 常量定义static final 用于定义类常量。
  6. 编译优化:编译时常量可被内联。

💡 一句话总结
final 字段是 Java 中实现不可变性线程安全的重要工具,合理使用可显著提升代码的健壮性和可维护性。

http://www.dtcms.com/a/491669.html

相关文章:

  • wordpress封采集站ip微信营销平台有哪些
  • Golang相关知识总结
  • LeetCode算法日记 - Day 73: 最小路径和、地下城游戏
  • 设计案例网站网站自身seo优化怎么做
  • 手绘风格制图新选择:Excalidraw+cpolar让视觉化工作流无缝协作
  • apt 安装任意软件产生 `libc6:amd64 package post-installation` 异常问题
  • Product Hunt 每日热榜 | 2025-10-16
  • 2025最新如何申请Google Translate API免费版图文教程
  • 提供常州微信网站建设单页企业网站模板
  • 证件阅读机在酒店与旅游业场景的应用
  • 深圳分销网站设计费用常平镇网站建设公司
  • 华为 FreeBuds SE4 ANC 如何手势调节音量?
  • Git怎么管理软件版本(代码,模型,配置等)
  • 翁虹庆爱女刘莳18岁生日 中式成人礼传承华夏底蕴
  • 苏州seo建站微信网站多少钱
  • Process Monitor 学习笔记(5.9):Procmon 的自动化操作——命令行选项
  • 荣耀手机Magic8系列都有哪些,分别通过硬件参数、性能参数、价格等方面进行详细对比
  • 合肥网站开发培训学校网站怎么做图片按按钮跳转
  • 西安专业做网站建设电子商务网站建设期中
  • 生态文明建设网站中城投建设集团网站
  • C++--- override 关键字 强制编译器验证当前函数是否重写基类的虚函数
  • LLM对话框项目技术栈重难点总结
  • 常州企业网站建设价格湛江宇锋网站建设
  • 网站开发实用吗搞钱路子一天两万
  • Ubuntu Server 系统安装图形界面远程工具(RDP)
  • 新版电脑微信4.1.x.x小程序逆向之——寻找小程序存放位置目录和__APP__.wxapkg
  • 我在高职教STM32(新05)——呼吸灯实验(基础版)
  • 丽泽桥网站建设wordpress分类列表去掉分类目录
  • 网站开发创业计划书模板宝安中心医院是什么级别
  • 华清远见25072班QT学习day2