您的位置:首页 > 编程语言 > Java开发

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

2017-11-09 22:01 295 查看
前段时间写项目的时候,遇到一个很有趣问题,我把内容简化一下放上来

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

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.不了解可变对象和不可变对象
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: