《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!

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

相关推荐
IT当时语_青山师__JAVA技术栈1 小时前
数组与链表深度解析:从内存布局到工业级实践
java·算法·面试
学习论之费曼学习法1 小时前
AI 入门 30 天挑战 - Day 29 - 面试准备指南
人工智能·面试·职场和发展
java1234_小锋1 小时前
Spring AI 2.0 开发Java Agent智能体 - 工具调用(Function Calling / Tools)
java·人工智能·spring
Cosmoshhhyyy1 小时前
《Effective Java》解读第 52 条:慎用重载
java·开发语言·windows
大大杰哥1 小时前
温故知新:Java 线程创建方式的演进与总结
java·开发语言·jvm
坐吃山猪1 小时前
Python34_装饰器知识
开发语言·python·ubuntu
凯瑟琳.奥古斯特1 小时前
死锁四大必要条件解析
java·开发语言·后端·职场和发展
xyq20241 小时前
React 事件处理
开发语言
冰的第三次元1 小时前
接口,抽象的避坑指南和多态的“两面派”真相
java