当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
*还有类似问题,如“简单谈谈按值传递与按引用传递”。
参考答案如下:是值传递,因为Java编程语言中只有值传递参数。
当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。
看着这个参考答案,好像懂了,却又总是感觉哪里不对,而对于这个问题,JACK的机器人一直比较迷糊。但在看过网友“且听风吟”这篇《Java:按值传递还是按引用传递详细解说》分析文章后,就基本明白这个到底是怎么一回事了。主要原因还是欠缺对Java的内存机制的深刻理解,下面引用一下其文中分享的内容。
举例对比分析
1. 什么是按值传递
指的是在方法调用时,传递的参数是按值的拷贝传递。示例如下:
public class TempTest {
private void test1(int a) {
//做点事情
}
public static void main(String[] args) {
TempTest t = new TempTest();
int a = 3;
t.test1(a);//这里传递的参数a就是按值传递
}
}
按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。示例如下:
public class TempTest {
private void test1(int a){
a = 5;
System.out.println("test1方法中的a="+a);
}
public static void main(String[] args) {
TempTest t = new TempTest();
int a = 3;
t.test1(a);//传递后,test1方法对变量值的改变不影响这里的a
System.out.println(”main方法中的a=”+a);
}
}
运行结果是:
test1方法中的a=5
main方法中的a=3
2. 什么是按引用传递
指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。示例如下:
public class TempTest {
private void test1(A a){
}
public static void main(String[] args) {
TempTest t = new TempTest();
A a = new A();
t.test1(a); //这里传递的参数a就是按引用传递
}
}
class A {
public int age = 0;
}
3. 按引用传递的重要特点
传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。示例如下:
public class TempTest {
private void test1(A a){
a.age = 20;
System.out.println("test1方法中的age="+a.age);
}
public static void main(String[] args) {
TempTest t = new TempTest();
A a = new A();
a.age = 10;
t.test1(a);
System.out.println(”main方法中的age=”+a.age);
}
}
class A{
public int age = 0;
}
运行结果如下:
test1方法中的age=20
main方法中的age=20*这里两个“a.age”的值相同的原因的是:只存在一个共同的“new A();”出来的内存空间,两个引用对象“a”指向的内容地址是相同,即两者操作的实际上就是同一个值。
4. 对上述例子的改变
理解了上面的例子,可能有人会问,那么能不能让按照引用传递的值,相互不影响呢?就是test1方法里面的修改不影响到main方法里面呢?
方法是在test1方法里面新new一个实例就可以了。改变成下面的例子,其中第3行为新加的:
public class TempTest {
private void test1(A a){
a = new A();//新加的一行
a.age = 20;
System.out.println("test1方法中的age="+a.age);
}
public static void main(String[] args) {
TempTest t = new TempTest();
A a = new A();
a.age = 10;
t.test1(a);
System.out.println(”main方法中的age=”+a.age);
}
}
class A{
public int age = 0;
}
运行结果为:
test1方法中的age=20
main方法中的age=10*这里两个“a.age”的值不同的原因是:两个“new A();”并不是同一个内存空间,所以两个引用对象“a”所指向的地址也是不同的,可以说两者当前是互不影响的。
总 结“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。
在Java里面只有基本类型和按照下面这种定义方式的String是按值传递,其它的都是按引用传递。就是直接使用双引号定义字符串方式:String str = "Java私塾"; 。