final在Java中到底有啥用?5个实际场景告诉你

写Java的时候,final这个关键字,它看起来挺简单,很多人用得不多,甚至不知道它到底能干啥。那它到底有什么用,怎么用才不显得是"为了用而用"。

一、final修饰变量:让值不能变

这个是最常见的用法。

比如你写一个工具类,里面有个固定的配置:

java 复制代码
public class Config {
    public static final String API_URL = "https://api.example.com/v1";
    public static final int TIMEOUT = 5000;
}

加上final之后,API_URL和TIMEOUT就不能被修改了。你要是不小心写成:

java 复制代码
API_URL = "https://new-api.com"; // 编译直接报错!

编译器就会提醒你:"兄弟,这值不能改。"

使用场景:配置项、常量、固定字符串。加上final,防止自己或别人手滑改掉。

二、final 修饰参数:防止方法里乱改参数

有时候写方法,传进来的参数你不希望被改动。

java 复制代码
public void processUser(final User user) {
    // user = null; // 这行会报错!
    user.setName("张三"); // 注意:这行是可以的!
}

这里final只保证user这个引用不能变(不能指向别的对象),但对象里面的属性还是可以改的。

使用场景:你在写一个复杂方法,怕自己手一抖把参数重新赋值了,加个final就安全了。特别是lambda里,外部变量必须是"有效final",加了更省心。

三、final修饰方法:不让子类乱覆盖

有时候你写了个方法,逻辑很关键,不希望被子类随便改。

java 复制代码
public class BaseService {
    public final void saveLog() {
        System.out.println("记录操作日志...");
    }
}

子类继承之后,就不能重写这个方法了:

java 复制代码
public class UserService extends BaseService {
    // @Override
    // public void saveLog() { } // 直接报错!
}

使用场景:核心流程、安全相关的逻辑。比如你公司的操作日志必须记录,那就用final锁住,谁也不能绕开。

四、final修饰类:彻底封死,不许继承

最狠的一种用法。

java 复制代码
public final class SecurityUtil {
    public static String encrypt(String data) {
        // 加密逻辑
        return "encrypted_" + data;
    }
}

这个类谁也不能继承:

java 复制代码
// public class MySecurity extends SecurityUtil { } // 报错!

使用场景 :工具类、安全类、核心类。你不希望别人扩展或篡改它的行为,就用final类。像String就是final的,就是为了安全。

五、实际开发中的小技巧

  1. 局部变量加final?

    虽然不常用,但在复杂的逻辑块里,给关键变量加final,能避免后续误改。

    java 复制代码
    final int total = calculateTotal();
    // 后面不管怎么写,total 不会被重新赋值
  2. 配合lambda使用

    Lambda里引用的外部变量必须是final或"有效final"。提前声明final,能避免编译错误。

    java 复制代码
    final String msg = "Hello";
    Runnable r = () -> System.out.println(msg); // 没问题

总结

  • 用在变量上:防止被改。
  • 用在参数上:防止方法里乱赋值。
  • 用在方法上:防止被重写。
  • 用在类上:防止被继承。

别小看final。它没有那么炫酷,但能帮我们少踩坑。尤其是在团队协作中,加上final,就等于告诉同时:"这个东西动不了" 代码写得稳,不是靠运气,而是靠这些小细节。

本文首发于微信公众号「刘大华的开发笔记」我是大华,专注分享前后端开发的实战笔记。 关注我,少走弯路,一起进步!

相关推荐
码事漫谈6 分钟前
消除AI幻觉,普通人能做的五件事
后端
金銀銅鐵2 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
AI人工智能+电脑小能手2 小时前
一次请求打几个下游,这个Java并行任务工具类6个方法按序聚合
java·线程池·并发编程·1024程序员节·批量处理·并行任务
Mk598783 小时前
给 Agent 装上对话框 —— AgentScope-Java 接入 Spring Boot 与 SSE 流式实战
后端
付威20233 小时前
从 Loop 到 Runtime:rpi Agent Loop 与 Cordis 的边界、取舍与组合
后端
IT_陈寒4 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端
paopaokaka_luck4 小时前
心理咨询管理系统(WebSocket实时沟通、基于用户的协同过滤、 ECharts多维分析、 预约业务流程、预约校验与定时处理)
java·vue.js·spring boot·mysql·spring·echarts·1024程序员节
2301_32241428044 小时前
springboot农产品交易平台的设计与实现08055-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·spring boot·redis·mysql·tomcat·maven·mybatis
考虑考虑5 小时前
JDK26的JEP 500属性
java·后端·java ee