JAVA中方法的值传递对参数(可变和不可变)的影响

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuajiehe1234567/article/details/78494598

前段时间写项目的时候,遇到一个很有趣问题,我把内容简化一下放上来

例如一个方法要求我传入一个自定义参数,然后将其改变状态

public class Dog {
    public Integer legs = 4;

    public Integer getLegs() {
        return legs;
    }

    public void setLegs(Integer legs) {
        this.legs = legs;
    }

    public void addLegs(Dog dog){
        dog.setLegs(dog.getLegs()+1);
    }

    public static void main(String[] args) {
        Dog dog = new Dog();
        System.out.println("legs-->"+dog.getLegs());
        dog.addLegs(dog);
        System.out.println("legs-->"+dog.getLegs());
    }
}

输出的结果自然是dog的legs属性变成了5
五条腿的狗!
这段类似的代码被我铭记于心,明白了引用数据类型的状态是可以在方法体内改变的,基本数据类型?基本数据类型连状态都没有,何谈改变?值传递你懂吗?方法体内部对形参(传入的参数)变量的操作是进行在传入的形参的copy上的,不是在直接操作这个变量!
比如将方法改成:

    public void addLegs(Dog dog){
        dog = new Dog();
        dog.setLegs(dog.getLegs()-1);
//      dog.setLegs(dog.getLegs()+1);
    }

输出的结果,自然是变成了两个4

直到又过两天,遇到了类似以下这段代码

    public void changeString(String str){
        str = str+"!";
    }

这个方法无论用什么姿势传入参数都不会修改原本参数对应的值,当时博主心里相当卧槽,不是说好都是引用数据类型吗?怎么你不一样啊
类似的还有

    public void changeInteger(Integer i){
        i = 8;
    }

不管是传1到9999999999都不会影响改变原有参数的值,这时如果没仔细了解,光看这些源码其实是很难理解的,甚至会产生“难道只有我自己定义的类才是引用数据类型?”这种想法,陷入深深的自我怀疑
到底是初学者学艺不精,还有培训班老师也不给力,这个问题虽然不大,用处也几乎没有,但总萦绕脑海久久不去。

原来,八种基本数据类型的包装类和String类是不可变的,每对其进行一次赋值或者改变其状态,都会将原本的变量指向一个新的对象,即改变了原有对象的地址,在这个方法体内就是将形参/copy指向了新的地址,而原有的实参指向的原来的对象并没有改变才导致了这样的结果。如果使用其它JDK中可变的类,比如StringBuffer就不会出现这种情况


避免三个错误认知:
1.变量当中存储的就是对象的值,或者说状态
2.方法体内的赋值和方法体外无关,只有返回值和方法体外有关
3.不了解可变对象和不可变对象

猜你喜欢

转载自blog.csdn.net/liuajiehe1234567/article/details/78494598
今日推荐