浅谈方法中参数加上final

本文深入探讨Java中使用final关键字修饰方法参数的意义与作用。通过具体示例解释了final如何阻止参数被重新赋值,有效避免意外修改带来的问题,并强调了无论基本类型还是引用类型参数加final都无法再赋值的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参数加final

1、斯坦福教授说的好,方法可以比喻成一台机器(面包机),没错,在我的机器(方法)里面,我要的参数加了final(要原料),你给我传过来的参数,机器里面就无法改了,也就是说在机器里的这个参数,一直指向的都是你传进来的参数。

[java]  view plain  copy
  1. public class FinalNBA {  
  2.     public static void main(String args[]) {  
  3.         Curry curry = new Curry();  
  4.         curry.setSmallName("small student");  
  5.         printAll(curry);  
  6.         System.out.println(curry);  
  7.     }  
  8.       
  9.       
  10.     public static void printAll(final Curry temp){  
  11.         temp.setSmallName("fk do it");  
  12.         System.out.println(temp.getSmallName());  
  13. //      temp = new Curry();  传送进来的Curry引用是final,不可以再赋值了,这里一定会报错哦!  
  14.     }  
  15. }  


2、总结,无论参数是基本数据类型,还是引用数据类型,只要加了final,不好意思,该参数不可以再赋值(实参传进来给形参,就相当于初始化完成)。。。。可以防止在方法里面不小心重新赋值,造成一些不必要的麻烦!!!


3、不加final的参数,可能会出现的错误是

[java]  view plain  copy
  1. public static void printAll(Curry temp){  
  2.         temp = new Curry(); //这就是出现的问题,又new了一个库里,与调用该方法时传进来的库里毫无关系了!!  
  3.         temp.setSmallName("fk do it");  
  4.         System.out.println(temp.getSmallName());  
  5.     }  



版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.youkuaiyun.com/cadi2011/article/details/51615514
个人分类:  Java 综合

<think>在Java中,在方法参数加上`final`关键字有以下几个作用: 1. **防止参数被重新赋值**:一旦参数被声明为`final`,在方法体内就不能再修改该参数的值(即不能重新赋值)。这可以防止在方法内部无意中修改了参数的值,从而避免潜在的逻辑错误。 2. **提高代码可读性和维护性**:通过将参数标记为`final`,可以明确地告诉其他开发者这个参数方法内部不会被改变,从而使得代码的意图更加清晰。 3. **支持匿名内部类**:在Java 8之前,如果需要在方法内部使用匿名内部类,并且该内部类需要访问方法参数,那么这些参数必须被声明为`final`。从Java 8开始,引入了“effectively final”的概念,即即使没有显式声明为`final`,只要参数方法内部没有被修改,就可以在匿名内部类或lambda表达式中使用。但是,显式声明为`final`可以确保参数不会被修改,从而避免错误。 4. **线程安全**:将参数声明为`final`可以确保在方法内部该参数不会被重新赋值,这在多线程环境中可能有助于提高代码的安全性(尽管它不能保证参数所引用的对象本身是不可变的)。 ### 示例代码 ```java public class FinalParameterExample { // 方法参数使用final修饰 public void printMessage(final String message) { // 以下语句如果取消注释,将导致编译错误,因为message是final的,不能重新赋值 // message = "Another message"; System.out.println(message); } // 在匿名内部类中使用(Java 8之前必须为final,现在可以不用显式声明,但显式声明可以防止修改) public void doSomethingWithAnonymousClass() { final int x = 10; // 在Java 8之前,这里必须声明为final Runnable r = new Runnable() { @Override public void run() { System.out.println(x); // 访问外部变量 } }; new Thread(r).start(); } // 在lambda表达式中使用(effectively final) public void doSomethingWithLambda() { int y = 20; // 这里没有声明为final,但它是effectively final的 Runnable r = () -> System.out.println(y); new Thread(r).start(); // 如果取消下面的注释,修改y的值,那么上面的lambda表达式将无法编译,因为y不再是effectively final // y = 30; } } ``` ### 解释 - 在`printMessage`方法中,参数`message`被声明为`final`,因此不能在方法体内重新赋值。 - 在`doSomethingWithAnonymousClass`方法中,局部变量`x`被声明为`final`,以便在匿名内部类中使用。在Java 8之前,这是必须的;在Java 8及以后,如果变量没有被修改,可以省略`final`,但显式声明可以防止后续修改。 - 在`doSomethingWithLambda`方法中,变量`y`虽然没有显式声明为`final`,但由于没有在初始化后修改,所以它是effectively final的,可以在lambda表达式中使用。如果尝试修改`y`,则会导致编译错误。 ### 总结 在方法参数上使用`final`关键字主要是为了: - 防止在方法内部修改参数的值。 - 提高代码的可读性和可维护性。 - 支持在匿名内部类中使用(在Java 8之前是必须的,现在则推荐使用effectively final,但显式声明`final`仍是一种好习惯)。 尽管在Java 8及以后版本中,由于effectively final的存在,显式使用`final`不再是必须的,但在团队开发中,根据编码规范,有时仍然推荐使用`final`来明确意图。 §§相关问题§§: 1. Java中`final`关键字可以修饰哪些结构? 2. 什么是effectively final?它和显式声明为`final`有什么区别? 3. 在lambda表达式中使用外部变量为什么要求是final或effectively final? 4. 在方法参数上使用`final`对性能有影响吗?</think>### 在方法参数上使用 `final` 的作用 在 Java 中,将方法参数标记为 `final` 主要有以下作用和意义: #### 1. **防止参数被重新赋值** - **作用**:禁止在方法内部修改参数的值(基本类型)或重新分配引用(引用类型)。 - **原因**:确保传入的参数值在方法逻辑中保持不变,避免意外修改导致的逻辑错误。 - **示例**: ```java public void process(final int id, final String name) { // id = 10; // 编译错误:无法修改 final 基本类型参数 // name = "Bob"; // 编译错误:无法修改 final 引用类型参数 System.out.println(id + ": " + name); } ``` #### 2. **支持匿名内部类访问(Java 8 之前)** - **作用**:在 Java 8 之前,匿名内部类若需访问外部方法参数,该参数**必须声明为 `final`**。 - **原因**:匿名内部类会拷贝外部变量,`final` 保证变量值在拷贝前后一致(避免数据不一致)。 - **示例**(Java 7): ```java public void oldWay(final int value) { Runnable r = new Runnable() { @Override public void run() { System.out.println(value); // 需 final 修饰 } }; new Thread(r).start(); } ``` #### 3. **明确设计意图(代码可读性)** - **作用**:向其他开发者明确“此参数不应在方法内被修改”。 - **原因**:提升代码可维护性,减少因参数被意外修改引发的 Bug。 #### 4. **线程安全辅助** - **作用**:`final` 参数方法内部不会被修改,在多线程环境下可减少同步需求。 - **原因**:不可变的值天然具备线程安全性(但需注意:`final` 仅限制引用不变,对象内部状态仍可能被修改)。 --- ### Java 8+ 的改进:Effectively Final 从 Java 8 开始,即使参数**未显式声明 `final`**,只要满足以下条件,匿名内部类或 Lambda 表达式仍可直接访问: 1. 参数方法内未被重新赋值。 2. 参数引用未指向新对象。 **示例**(Java 8+): ```java public void modernWay(int value) { // 无需显式 final Runnable r = () -> System.out.println(value); // 合法:value 是 effectively final new Thread(r).start(); // value = 10; // 若取消注释,value 不再是 effectively final,导致编译错误 } ``` --- ### 总结对比 | **场景** | **Java 7 及之前** | **Java 8+** | |------------------------|-----------------------------------|--------------------------------------| | **匿名内部类访问参数** | 必须显式 `final` | 支持 effectively final | | **Lambda 访问参数** | 不支持 Lambda | 支持 effectively final | | **禁止参数修改** | 显式 `final` 强制不可修改 | 显式 `final` 或 effectively final 均可 | --- ### 何时推荐使用 `final`? 1. 需要明确禁止参数修改时。 2. 维护旧代码(Java 7 及以下)。 3. 团队编码规范要求明确标识不可变参数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值