《Java 100 天进阶之路》第14篇:Java final关键字详解

第14篇:Java final关键字详解

📌 系列导航《Java 100 天进阶之路》完整目录 |

⬅️ 上一篇:第13篇:JDK和JRE、final与static、堆和栈|

➡️ 下一篇:第15篇:Java控制流程语句

一、核心知识点

  • final修饰类:不能被继承
  • final修饰方法:不能被重写(但可以被重载)
  • final修饰变量:基本类型值不可变,引用类型引用不可变(但对象内部可变)
  • 空白final:声明时不赋值,必须在构造方法中赋值
  • static final:类常量,命名全大写,下划线分隔

二、通俗讲解(1分钟开心学)

1. final修饰类

表示这个类是"最终版",不允许被继承。比如String类就是final的,所以你不能写class MyString extends String

为什么String要设计成final?

  • 安全性:防止子类恶意篡改字符串行为。
  • 常量池:final保证了字符串不变性,可以让相同内容的字符串共享对象。
  • 线程安全:不可变对象天然线程安全。

2. final修饰方法

表示这个方法不能被子类重写。常在模板方法模式中使用,把骨架方法声明为final,让子类只能重写某些步骤。

3. final修饰变量

  • 基本类型:值不能改变,名副其实的常量。
  • 引用类型 :引用地址不能变,但对象内部属性可以变(除非对象本身是不可变的,如String)。

4. 空白final

声明时不给值,但在所有的构造方法中必须赋值。这提供了一种灵活性:每个对象可以有不同的常量值,但一旦构造完成就不能改变。

5. static final

类常量,通常用大写字母加下划线命名,例如public static final double PI = 3.14;,在类加载时初始化,全局唯一。

三、实操代码案例 + 场景说明

场景:定义一个"人"类,每个人有唯一的身份证号(一旦创建不能修改),且有一个通用的最大年龄常量。

java 复制代码
public class Person {
    // 类常量(static final)
    public static final int MAX_AGE = 150;
    
    // 空白final实例变量:每个对象只能赋值一次
    private final String idCard;  // 身份证号
    
    private String name;
    
    public Person(String idCard, String name) {
        this.idCard = idCard;   // 必须在构造方法中赋值
        this.name = name;
    }
    
    // 不允许修改身份证号,所以没有setIdCard()
    public String getIdCard() { return idCard; }
    
    public void setName(String name) { this.name = name; }
    
    // final方法:子类不能重写
    public final void showId() {
        System.out.println("身份证:" + idCard);
    }
}

// final类示例
final class SecurityUtil {
    // 工具类,不希望被继承
    public static void encrypt(String data) { }
}
// class MySecurity extends SecurityUtil {}  // 编译错误,不能继承final类

final引用变量陷阱演示

java 复制代码
final StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");   // 可以,对象内部改变了
System.out.println(sb); // Hello World

// sb = new StringBuilder("New"); // 编译错误,引用不能指向新对象

四、避坑要点

错误/误区 后果 正确做法
认为final数组或集合内容不可变 错误理解,数组元素、集合元素仍可修改 需要不可变集合用Collections.unmodifiableList
空白final在某个构造方法中忘记赋值 编译错误 确保所有构造方法都赋值
final方法被误认为效率一定更高 早期优化,现代JVM会自动内联 优先关注设计,而非性能
final类中所有方法自动成为final 是的,但理解即可 不需要额外加final

五、面试高频考点

Q1:final、finally、finalize的区别?

final是关键字,用于限制类、方法、变量;finally是异常处理的最后执行块;finalizeObject的方法,GC前调用(已弃用)。

Q2:String为什么要设计成final?

  1. 安全性(防止继承后篡改);2. 字符串常量池需要不可变性;3. 天然线程安全;4. hashCode可缓存提高性能。

Q3:final int[] arr = {1,2,3}; arr[0]=10; 合法吗?为什么?

合法。arr引用不可变,但数组元素可变。只有数组引用本身不能指向新数组。

六、练习题

  1. 代码填空 :写出一个带有空白final变量id的类,要求在构造方法中赋值。
  2. 设计 :为什么工具类(如Math)常常用final类 + 私有构造方法?尝试实现一个简单的工具类。
  3. 判断final Person p = new Person(); p = new Person(); 能否编译通过?

📊 你的学习进度

  • 当前:第10篇 / 共44篇 · 第二阶段:核心语法与面向对象(第5~20篇)
  • ✅ 已完成:第1~9篇
  • 📖 正在学:第10篇
  • ⏳ 待学习:第11~44篇

👉 📚 完整目录 & 学习指南 | 🔥 订阅本专栏,不错过每一篇

💡 本专栏每篇都包含:避坑表 + 面试高频考点 + 练习题。每天30分钟,100天拿offer!


👉 下一篇预告

《Java控制流程语句》

内容简介:if-else、switch-case(含箭头语法)、for/while/do-while循环,break/continue/return跳转。

💡 学完这篇,你将掌握所有流程控制语句,能写出任何逻辑的程序。

📌 《Java 100 天进阶之路 | 从入门到上岗就业》 每天一篇,建议收藏 + 关注 ,一起100天拿offer!

👉 点击关注我,更新后第一时间收到推送!

相关推荐
曾几何时`9 小时前
Go(三)GC垃圾回收
开发语言
并不喜欢吃鱼9 小时前
一.C++11:统一列表初始化 + std::initializer_list 超详细精讲
开发语言·c++
Gopher_HBo9 小时前
Go语言学习笔记(四)条件控制语句
后端
橘子星9 小时前
从零上手!Node.js 快速搭建生成式 AI 后端项目|密钥安全 + 完整可运行代码
前端·后端
砍材农夫9 小时前
物联网实战:Spring Boot MQTT | 模拟器Paho客户端sdk入门
后端
只一9 小时前
零基础搭建你的专属AI后端:从环境配置到异步魔法
后端
CHHH_HHH9 小时前
【C++】二叉搜索树全面升级,深度剖析AVL树
开发语言·数据结构·c++·算法·stl
shelter9 小时前
一文讲清楚Spring Aop失效场景以及失效背后的原理
java
奋斗的小方9 小时前
Java基础篇09(2):项目实战之基于swing的石头迷阵
java·开发语言
Raink老师9 小时前
【AI面试临阵磨枪-90】Skill 之间如何调用、依赖、组合、编排?
面试·职场和发展