今天看了Java中的传值和传引用,对于这一块开始的时候不太能理解,通过查阅其他几篇blog,将自己的理解记录下来:
比较好的几篇blog:http://blog.csdn.net/houpuhope/article/details/7449377;
首先对于传值和传引用需要有一个初步的理解就是,通过传值的方式传进来的参数修改了,对原变量并没有什么影响;
而,通过传引用的方式修改的,原变量值也跟着改变。下面进行详细的解析:
1.对于基本类型Java是按照传值传递的:
public class Test {
public static void test(boolean test) {
test = ! test;
System.out.println("In test(boolean): test = " + test);
}
public static void main(String[] args) {
boolean test = true;
System.out.println("Beforetest(boolean) : test = " + test);
test(test);
System.out.println("Aftertest(boolean) : test = " + test);
}
}
本题的输出结果是:
Beforetest(boolean) : test = true
In test(boolean) : test = false
After test(boolean) : test = true
不难看出,虽然在 test(boolean) 方法中改变了传进来的参数的值,但对这个参数源变量本身并没有影响,即对 main(String[]) 方法里的 test 变量没有影响。那说明,参数类型是简单类型的时候,是按值传递的。以参数形式传递简单类型的变量时,实际上是将参数的值作了一个拷贝传进方法函数的,那么在方法函数里再怎么改变其值,其结果都是只改变了拷贝的值,而不是源值。
2.对于对象类型,Java是按照传引用的方式传递:
这里举一个典型的列子:
public class Test {
public static void main(String[] args) {
StringBuffer a = newStringBuffer("Hello");
StringBuffer b = a;
b.append(", World");
System.out.println("a is "+ a);
}
}
输出结果:
a is Hello, World
这是因为StringBuffer产生一块内存空间,相关的增、删、改操作都在其中进行。所以为其添加一句,“,World”仍然是在同一段内存地址上进行;
但是还有一个特例的情况:
public class Test {
public static void test(String str) {
str = "World";
}
public static void main(String[] args) {
String string = "Hello";
test(string);
System.out.println(string);
}
}
输出的结果:
Hello
这是因为当执行str="World"时,其过程为:首先系统会自动生成一个新String对象,并把这个新对象的值设为“World”,然后把这个对象的引用赋值给str;必须清楚一点,String类是一个final类型的,因此,不可以继承和修改这个类。str=“World”,其实是让Java隐含的生成一个新的String对象。当函数结束时,str消失,原来的内存地址上的内容未加改变,所以打印结果还是“Hello";
所以引用一句经典的话总结:结果,就像光到底是波还是粒子的问题一样,Java 方法的参数是按什么传递的问题,其答案就只能是:即是按值传递也是按引用传递,只是参照物不同,结果也就不同。