一、最开始的示例 写代码最重要的就是实践, 不经过反复试验而得出的说辞只能说是凭空遐想罢了。 所以, 在本文中首先以一个简单示例来抛出核心话题: public class StringAsParamOfMethodDemo { public static void main(String[] args) { StringAsParamOfMethodDemo StringAsParamOfMethodDemo=new StringAsParamOfMethodDemo(); StringAsParamOfMethodDemo.testA(); } private void testA() { String originalStr = "original"; System.out.println("Test A Begin:"); System.out.println("The outer String: " + originalStr); simpleChangeString(originalStr); System.out.println("The outer String after inner change: " + originalStr) System.out.println("Test A End.");System.out.println(); } public void simpleChangeString(String original) { original = original + " is changed!"; System.out.println("The changed inner String: " + original);
} 这段代码的逻辑是这样的:先赋值一个 String 类型的局部变量,然后把这个变量作为 参数送进一个方法中,在这个方法中改变该变量的值。编译运行之后,发现输出结果是这样 的: Test A Begin: The outer String: original The changed inner String: original is changed! The outer String after inner change: original Test A End. 这个结果表明在方法内部对 String 类型的变量的重新赋值操作并没有对这个变量的原 型产生任何影响。好了,这个示例的逻辑和运行结果都展示清楚了,接下来我们来对这个小 程序进行分析。在这之前我们先来回顾下 Java 中所谓的“传值”和“传引用”问题。 二、Java 中的“传值”和“传引用”问题 许多初学 Java 的
程序员都在这个问题上有所思索,那是因为这是所谓的“C 语言的传 值和传指针问题”在 Java 语言上同类表现。 最后得出的结论是: 在
Java 中,当基本类型作为参数传入方法时,无论该参数在方法内怎样被改变,外部 的变量原型总是不变的,代码类似上面的示例: int number = 0; changeNumber(number) {number++}; //改变送进的 int 变量 System.out.println(number); //这时 number 依然为 0
这就叫做“值传递”,即方法操作的是参数变量(也就是原型变量的一个值的拷贝)改 变的也只是原型变量的一个拷贝而已,而非变量本身。所以变量原型并不会随之改变。 但当方法传入的参数为非基本类型时(也就是说是一个对象类型的变量),方法改变参 数变量的同时变量原型也会随之改变,代码同样类似上面的示例: StringBuffer strBuf = new StringBuffer(“original”); changeStringBuffer(strBuf) {strbuf.apend(“ is changed!”)} //改变送进 的 StringBuffer 变量 System.out.println(strBuf); //这时 strBuf 的值就变为了 original is changed! 这种特性就叫做“引
用传递”,也叫做传址,即方法操作参数变量时是拷贝了变量的引 用,而后通过引用找到变量(在这里是对象)的真正地址,并对其进行操作。当该方法结束 后,方法内部的那个参数变量随之消失。但是要知道这个变量只是对象的一个引用而已,它 只是指向了对象所在的真实地址,而非对象本身,所以它的消失并不会带来什么负面影响。 回头来看原型变量,原型变量本质上也是那个对象的一个引用(和参数变量是一样一样的), 当初对参数变量所指对象的改变就根本就是对原型变量所指对象的改变。所以原型变量所代 表的对象就这样被改变了,而且这种改变被保存了下来。 了解了这个经典问题,很多细心的读者肯定会立刻提出新的疑问:“可是 String 类型 在 Java 语言中属于非基本类型啊!它在方法中的改变为什么没有被保存下来呢!”的确,这 是个
问题,而且这个