java中的数值传递为值传递
在正式开说之前先简单的写一个引子:
public static void main(String[] args) { int a = 0; int b = 1; }
这个代码中定义了一个变量a 和 变量b 值分别为 0 和 1
我们将其输出显而易见的数值为
public static void main(String[] args) { int a = 0; int b = 1; System.out.println("a = " + a + ", b = " + b); }
a=0 b=1
如果我们想要交换他们的值该怎么办?
聪明的你很快的想出了对应的办法:
public static void main(String[] args) { int a = 0; int b = 1; exchange(a, b); } public static void exchange(int x,int y) { int tmp = x; x = y; y = tmp; System.out.print("a = " + x); System.out.println(" b = " + y); }
那么我问聪明的你,在这个方法中 有两个形参,x,y 它们分别传入了a,b
在这个操作中,究竟是修改了ab的值,还是对xy进行的操作呢??
这或许不直观,我们再写一个新的方法去看看吧!
public static void main(String[] args) { int a = 1; System.out.println("Change before:" + a); method(a); System.out.println("Change after:" + a); } public static void method(int a) { a = 2; }
这个方法定义了一个a 的形参 并在里面对a进行了赋值。让我们猜猜他的运行结果是什么?
Change before:1 Change after:1
两个1?
是的,就是两个1,这是因为在java中,数值的传递是值传递。传递的是变量值的副本,而非变量值本身。
这样就理解了前面的method方法执行后为什么两者都是1了,同时也说明了,exchange方法其实是对x,y的操作,而非a,b!
那这是否有例外呢?
StringBuilder与String的区别在于可变性,StringBuilder可以更加方便的进行后续的修改,这也是用StringBuilder而不用String的原因。
public static void main(String[] args) { StringBuilder sb = new StringBuilder("Hello"); change(sb); System.out.println(sb); } public static void change(StringBuilder builder) { builder.append(" World"); }
大家猜一猜这个代码的运行结果是什么呢?
依照前面的值传递,我们将变量sb传入到change方法内并在内部更改了它,我们理应更改的是它的副本,所以再次输出的结果应为Hello? 对吗?我们运行看一下!
Hello World
进程已结束,退出代码为 0
哦?!运行结果显示为Hellow World!为什么?
的确对于引用类型,传递的是对象引用的副本(即内存地址的拷贝),而非对象本身,但是如前文中的builder 与 sb 指定的是同一对象,所以对对象的修改会影响原对象!
那么是不是意味着只要我们在原来的基础上new 一个新的对象是不是结果就会有所变化?
public static void main(String[] args) { StringBuilder sb = new StringBuilder("Hello"); change(sb); System.out.println(sb); } public static void change(StringBuilder builder) { builder = new StringBuilder(" World"); } Hello 进程已结束,退出代码为 0
我们将代码简单修改,运行可以发现,结果变成了Hello!
这也对应的前文中的 指定同一对象时对对象的修改会影响原对象,而我们在这个修改后的方法内new了一个新的StringBuilder对象,所以修改不会影响原对象。
END
2⌇●﹏●⌇2
222