先看一段代码:
public class javaTest { PRivate int paraInt = 10; public int getParaInt() { return paraInt; } public void setParaInt(int paraInt) { this.paraInt = paraInt; } public void tryChangeBasicData(int para){ para = 100; System.out.println("inner tryChangeBasicData method:para = " + para); } public void tryChangeObject(JavaTest jTest){ jTest.setParaInt(100); System.out.println("inner tryChangeObject method:para = " + jTest.getParaInt()); } public static void main(String[] args) { JavaTest jTest = new JavaTest(); System.out.println("基本数据类型作为参数传递"); System.out.println("before method: " + jTest.getParaInt()); jTest.tryChangeBasicData(jTest.getParaInt()); System.out.println("after method: " + jTest.getParaInt()); System.out.println(""); System.out.println("对象引用作为参数传递"); System.out.println("before method: " + jTest.getParaInt()); jTest.tryChangeObject(jTest); System.out.println("after method: " + jTest.getParaInt()); }}运行上段代码得到:
基本数据类型作为参数传递 before method: 10 inner tryChangeBasicData method:para = 100 after method: 10 *** 对象引用作为参数传递 before method: 10 inner tryChangeObject method:para = 100 after method: 100
实际上是对参数 A 做了一个值拷贝 B,传递的参数是 B,然后所有操作是针对 B 的,因此不会影响到原参数 A。
可以参考上段代码,tryChangeBasicData() 前后 paraInt 值并没有改变。
实际上是对引用 X 做了一个拷贝引用 Y,传递的参数是 Y,所有操作都是针对 Y 的,但因为 X 和 Y 指向同一个地址,所以通过引用 Y 操作对象等同于使用 X 操作对象。
可以参考上面代码,tryChangeObject() 对 Y 指向的地址空间内的变量进行修改,X 取得的变量值是修改后的值。
String 在方法中作为参数传递,我们不用考虑传递的是引用还是值得拷贝,因为 String 本身一旦定义了就不可修改,做了“修改”(比如使用连接符做拼接)后就变成另外一个对象了,不会影响原对象。
究竟是按值传递还是按引用传递,这点不重要,因为不同的人对这两个定义的理解不一样。
真正需要明白的是: 基本数据类型(包括装箱的基本数据类型)传递的是值得拷贝,在方法中针对这个参数做任何事情都不会影响原参数; 对象引用传递的是引用的拷贝,但是无论拷贝多少次,引用指向的地址从未变过,因此可以通过此引用的拷贝修改原对象的一些属性。
所以当提起 Java 语言是值传递还是引用传递的时候,不妨换个理解方式,那就是传过去的对象或引用会不会影响原对象。
新闻热点
疑难解答