Java方法涉及 :方法实参、方法形参、方法返回值。
这里着重分析一下Java方法参数,因为经常容易混淆。
Java 参数分基本类型与引用类型。
基本类型例子:
public class MethodChangeValue { private void changeValue(int pValue) { pValue = 5; } public static void main(String[] args) { MethodChangeValue test = new MethodChangeValue(); int value = 100; test.changeValue(value); System.out.println(value); } } /* output ~ 100 * */
从上面例子的输出结果可以看出,无论changeValue方法中把参数修改为5或者其他值都不会影响传入参数本身,说明方法形参如果是基本类型仅仅是值传递,方法内的任何修改都不影响传入的参数本身。
下面再来看一个引用类型的例子:
public class MethodChangeReferenceValue { private void changStringReferenceValue(StringBuilder value) { value.delete(0, value.length()); value.append("new value"); } public static void main(String[] args) { MethodChangeReferenceValue test = new MethodChangeReferenceValue(); StringBuilder str = new StringBuilder("old value"); test.changStringReferenceValue(str); System.out.println(str); } } /* output ~ * new value * */
从上面例子可以看出往changStringReferenceValue方法传递的是StringBuilder对象的引用,在changStringReferenceValue方法中修改引用的值,再main方法中输出的值是在方法中修改过的值,说明如果传递的是一个引用类型可以在方法中直接进行修改。
引用类型的参数都是达到以上的效果吗?下面来例子再看看另外一种情况
public class MethodChangeRefrence { private void changeStringReference(StringBuilder value) { value = new StringBuilder("new value"); } public static void main(String[] args) { MethodChangeRefrence testReference = new MethodChangeRefrence(); StringBuilder str = new StringBuilder("old value"); testReference.changeStringReference(str); System.out.println(str); } } /* output ~ * old value * */
从上面例子的输出看到一个很奇怪的现象,明明传递的是一个引用类型,按照之前的经验方法内可以对其进行修改,但是从打印的结果来看根本就没有对引用的内容造成任何印象,这是为什么?
其实方法传递的引用类型准确点说传递的是对象的引用地址的一个拷贝,changeStringReference方法传入的str引用与方法从形参获取到的value是在栈中保存的两份保存同一个str对象引用地址,所以在方法内value = new StringBuilder("new value"); 等于是针对形参value指向新创建的对象,引用保存新创建对象的内容地址。
参考资料:
Java基本功——Reference
http://dreamhead.blogbus.com/logs/2005/05/1189478.html
原理讲解
java参数传递(超经典)
画图解释,更容易理解
《Thinking in Java 4》 2.5
《Java 核心技术基础卷》 4.5