用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内容时也会报错。


参考链接

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值