用final关键字修饰java方法中的参数
文章目录
前言
有实际项目应用中,经常遇到final修饰参数的情况。
例如:
public void Method(final int i){
System.out.println(i);
}
1、为什么要用final关键字修饰方法中的参数
1.防止入参内容后续被修改,保证调用方传入数据的唯一性。
2.对方法体内的编码内容进行约束。
2、final关键字修饰类型
2.1修饰基本类型
final修饰参数后不能在方法体内修改参数的值。
正常情况如下:
package finaltest;
public class FinalTest {
public static void main(String[] args) {
Number number = new Number();
number.numberMethod(1);
}
}
class Number{
public void numberMethod(final int n){
System.out.println(n);
}
}
结果为:
1
进程已结束,退出代码为 0
方法体内修改入参代码如下:
package finaltest;
public class FinalTest {
public static void main(String[] args) {
Number number = new Number();
number.numberMethod(1);
}
}
class Number{
public void numberMethod(final int n){
n = 2;//方法体内修改入参
System.out.println(n);
}
}
返回结果为:
java: 不能分配最终参数n
提示为编译时报错。
2.2修饰引用类型
修饰引用类型主要是可以更改内容,不能修改地址
2.2.1修饰list类型
修饰list类型可以更改内容,不能更改地址。
正常输入如下:
package finaltest;
import java.util.ArrayList;
public class FinalTest1 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
Number1.numberMethod1(arrayList);
System.out.println(arrayList);
}
}
class Number1{
public static void numberMethod1(final ArrayList<Integer> arrayList){
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
}
}
返回结果为:
[1, 2, 3]
进程已结束,退出代码为 0
如果将list在方法体内重新new一个
package finaltest;
import java.util.ArrayList;
public class FinalTest1 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
Number1.numberMethod1(arrayList);
System.out.println(arrayList);
}
}
class Number1{
public static void numberMethod1(final ArrayList<Integer> arrayList){
arrayList = new ArrayList<Integer>();//方法体内修改入参
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
}
}
返回结果报错:
java: 不能分配最终参数arrayList
提示同为编译模块时报错。
2.2.2修饰map类型
map类型与list类型情况相似,可以变更其内容,不能变更其地址。
正常代码如下:
package finaltest;
import java.util.HashMap;
import java.util.Map;
public class FinalTest2 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
Number2.numberMethod2(map);
System.out.println(map.get(0));
System.out.println(map.get(1));
System.out.println(map.get(2));
}
}
class Number2{
public static void numberMethod2(final Map<Integer,String> map){
map.put(0, "a");
map.put(1, "b");
map.put(2, "c");
}
}
返回结果为:
a
b
c
进程已结束,退出代码为 0
如果将map在方法体内重新new一个
package finaltest;
import java.util.HashMap;
import java.util.Map;
public class FinalTest2 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
Number2.numberMethod2(map);
System.out.println(map.get(0));
System.out.println(map.get(1));
System.out.println(map.get(2));
}
}
class Number2{
public static void numberMethod2(final Map<Integer,String> map){
map = new HashMap<Integer,String>();//方法体内修改入参
map.put(0, "a");
map.put(1, "b");
map.put(2, "c");
}
}
提示同为编译模块时报错。
2.2.3修饰string类型
与list、map类似,String在变更其地址时也会报错。因为String类型的变量每次在重新赋值的时候,在堆中会重新创建一个新的区域,这样就改变了其在栈中的地址,所以用final修饰的String类型变量无法重新赋值。
package finaltest;
public class FinalTest3 {
public static void main(String[] args) {
String a = "1";
Number3.numberMethod3(a);
System.out.println(a);
}
}
class Number3{
public static void numberMethod3(final String string){
string = "2";//方法体内修改入参
}
}
报错为:
java: 不能分配最终参数string
2.2.3修饰对象类型
对象类型同样是内容可以变更,地址不能变更。
正常代码如下:
package finaltest;
public class FinalTest4 {
public static void main(String[] args) {
FinalTest4.NumberTest(new Number4());
}
public static void NumberTest(final Number4 number4){
number4.setNumber1(1);
number4.setNumber2(2);
System.out.println(number4.toString());
}
}
class Number4{
private Integer number1;
private Integer number2;
public Integer getNumber1() {
return number1;
}
public void setNumber1(Integer number1) {
this.number1 = number1;
}
public Integer getNumber2() {
return number2;
}
public void setNumber2(Integer number2) {
this.number2 = number2;
}
@Override
public String toString() {
return "Number4{" +
"number1=" + number1 +
", number2=" + number2 +
'}';
}
}
返回结果为:
Number4{number1=1, number2=2}
进程已结束,退出代码为 0
报错代码如下:
package finaltest;
public class FinalTest4 {
public static void main(String[] args) {
FinalTest4.NumberTest(new Number4());
}
public static void NumberTest(final Number4 number4){
number4.setNumber1(1);
number4.setNumber2(2);
System.out.println(number4.toString());
Number4 number = new Number4();
number4 = number;//方法体内修改入参
}
}
class Number4{
private Integer number1;
private Integer number2;
public Integer getNumber1() {
return number1;
}
public void setNumber1(Integer number1) {
this.number1 = number1;
}
public Integer getNumber2() {
return number2;
}
public void setNumber2(Integer number2) {
this.number2 = number2;
}
@Override
public String toString() {
return "Number4{" +
"number1=" + number1 +
", number2=" + number2 +
'}';
}
}
报错为:
java: 不能分配最终参数number4
总结
在方法参数前面加final关键字是为了防止传入数据在方法体中被修改。
在参数进行final修饰时,如果是基本类型,那么在方法体内更改数值会报错。如果是引用类型,修改内容不会报错,但是修改地址会报错,其中String比较特别,修改String内容时也会更改其地址,所以修改String内容时也会报错。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了