JAVA中方法的值传递对参数(可变和不可变)的影响
2017-11-09 22:01
295 查看
前段时间写项目的时候,遇到一个很有趣问题,我把内容简化一下放上来
例如一个方法要求我传入一个自定义参数,然后将其改变状态
输出的结果自然是dog的legs属性变成了5
五条腿的狗!
这段类似的代码被我铭记于心,明白了引用数据类型的状态是可以在方法体内改变的,基本数据类型?基本数据类型连状态都没有,何谈改变?值传递你懂吗?方法体内部对形参(传入的参数)变量的操作是进行在传入的形参的copy上的,不是在直接操作这个变量!
比如将方法改成:
输出的结果,自然是变成了两个4
直到又过两天,遇到了类似以下这段代码
这个方法无论用什么姿势传入参数都不会修改原本参数对应的值,当时博主心里相当卧槽,不是说好都是引用数据类型吗?怎么你不一样啊
类似的还有
不管是传1到9999999999都不会影响改变原有参数的值,这时如果没仔细了解,光看这些源码其实是很难理解的,甚至会产生“难道只有我自己定义的类才是引用数据类型?”这种想法,陷入深深的自我怀疑
到底是初学者学艺不精,还有培训班老师也不给力,这个问题虽然不大,用处也几乎没有,但总萦绕脑海久久不去。
原来,八种基本数据类型的包装类和String类是不可变的,每对其进行一次赋值或者改变其状态,都会将原本的变量指向一个新的对象,即改变了原有对象的地址,在这个方法体内就是将形参/copy指向了新的地址,而原有的实参指向的原来的对象并没有改变才导致了这样的结果。如果使用其它JDK中可变的类,比如StringBuffer就不会出现这种情况
避免三个错误认知:
1.变量当中存储的就是对象的值,或者说状态
2.方法体内的赋值和方法体外无关,只有返回值和方法体外有关
3.不了解可变对象和不可变对象
例如一个方法要求我传入一个自定义参数,然后将其改变状态
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.不了解可变对象和不可变对象
相关文章推荐
- Kotlin传递可变长参数给Java可变参数方法
- java get传递方法传递参数时,参数用utf8编码的解决方法
- 关于"Java中方法参数的传递方式"的探讨
- Java常见笔试面试题目深度剖析系列之:Java方法参数传递详解
- Java1.5新功能可变长方法参数-varargs
- java get传递方法传递参数时,参数用utf8编码的解决方法
- params关键字给方法传递可变数量的参数
- Java方法的可变参数类型
- Java方法中的可变参数
- java方法参数传递问题
- 在Java中方法参数的传递,对象是传递引用
- java学习笔记(四)----对象、数组作为参数传递,静态变量、静态方法的使用,内部类,使用文档注释
- Java方法的参数是按值传递的.
- 二十三:向方法传递可变数量的参数(使用params参数)
- Java 方法中参数传递
- JAVA中方法的参数是按值传递的,有个例子很经典
- Eclipse运行java程序为主方法传递参数
- java get传递方法传递参数时,参数用utf8编码的解决方法
- 我的理解:Java 中方法的参数全部都是按“值”传递的
- java get传递方法传递参数时,参数用utf8编码的解决方法