基本概念
-
按值调用(call by value):方法接收的是调用者提供的值
-
按引用调用(call by reference):方法接收的是调用者提供的变量地址(C语言的指针)
区别:能否改变变量值
剖析
基本数据类型
public class CallByValue { private static int x=5; public static void updateValue(int value){ value = 3 * value; } public static void main(String[] args) { System.out.println("调用前x的值:"+x); updateValue(x); System.out.println("调用后x的值:"+x); } }
输出结果:
5
5
=》x的值未被改变
结论:当传递方法参数类型为基本数据类型(数字以及布尔值)时,一个方法是不可能修改一个基本数据类型的参数
引用类型
package com.bat.example; public class User { private String name; private int age; public User(String name, int age) { this.name=name; this.age=age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return name+" "+age; } }
package com.bat.example; public class CallByValue { private static User user=null; public static void updateUser(User student){ student.setName("david"); student.setAge(18); } public static void main(String[] args) { user = new User("lucy",26); System.out.println("调用前user的值:"+user.toString()); updateUser(user); System.out.println("调用后user的值:"+user.toString()); } }
输出结果:
调用前user的值:lucy 26
调用后user的值:david 18
结论:当传递方法参数类型为引用数据类型时,一个方法将修改一个引用数据类型的参数所指向对象的值
疑问:这不是按引用传递吗?再看下个例子
package com.bat.example; public class CallByValue { private static User user=null; private static User stu=null; /** * 交换两个对象 * @param x * @param y */ public static void swap(User x,User y){ User temp =x; x=y; y=temp; } public static void main(String[] args) { user = new User("david",26); stu = new User("lucy",18); System.out.println("调用前user的值:"+user.toString()); System.out.println("调用前stu的值:"+stu.toString()); swap(user,stu); System.out.println("调用后user的值:"+user.toString()); System.out.println("调用后stu的值:"+stu.toString()); } }
运行结果:
调用前user的值:david 26
调用前stu的值:lucy 18
调用后user的值:david 26
调用后stu的值:lucy 18
=》对象引用实际上进行的是值传递,只是拷贝了引用的值罢了,之所以能修改引用数据是因为它们同时指向了一个对象,
但这仍然是按值调用而不是引用调用