java基本数据类型传递与引用传递区别详解

程序设计语言中有关参数传递给方法(或函数)的两个专业术语:

按值调用(call by value)
按引用调用(call by reference)

所谓的按值调用表示方法接收的是调用着提供的值

按引用调用则表示方法接收的是调用者提供的变量地址

这里我们需要注意的是一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值,这句话相当重要


1.基本数据类型的传递和修改

public static void main(String[] args) {
		int x = 10;
		System.out.println(x);
		setInt(x);
		System.out.println(x);
		
	}
	/*
	 * 基本数据类型的传递和修改
	 */
	public static void setInt(int x) {
		x = x * 3;
	}

结果

10
10

说明x并没有被修改

参照下图

image.png

分析:

1)value被初始化为x值的一个拷贝(也就是10)

2)value被乘以3后等于30,但注意此时x的值仍为10!

3)这个方法结束后,参数变量value不再使用,被回收。

结论:当传递方法参数类型为基本数据类型(数字以及布尔值)时,一个方法是不可能修改一个基本数据类型的参数。


2.引用数据类型的传递和修改

用户对象

public class UserInfo {
    private int id;
    private String name;
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
}


2.1内部方法修改对象值后,外部对象值也被更新了

public static void main(String[] args) {
    UserInfo user1 = new UserInfo();
    user1.setId(1);
    user1.setName("张三");
    System.out.println(user1.getId()+" - "+user1.getName());
    System.out.println("=====setUser1=====");
    setUser1(user1);
    System.out.println(user1.getId()+" - "+user1.getName());
}
public static void setUser1(UserInfo ui) {
    ui.setId(10);
    ui.setName("修改后的名字");
}

结果

1 - 张三
=====setUser1=====
10 - 修改后的名字

分析:

1)ui变量被初始化为user1值的拷贝,这里是一个对象的引用。

2)调用ui变量的set方法作用在这个引用对象上,user1和ui同时引用的User对象内部值被修改。

3)方法结束后,ui变量不再使用,被释放,而user还是没有变,依然指向User对象。

结论:当传递方法参数类型为引用数据类型时,一个方法将修改一个引用数据类型的参数所指向对象的值。

参照下图

image.png


2.2内部方法重新指向新的对象,修改值后,外部对象值未被更新

public static void main(String[] args) {
    UserInfo user1 = new UserInfo();
    user1.setId(1);
    user1.setName("张三");
    System.out.println(user1.getId()+" - "+user1.getName());
    System.out.println("=====setUser2=====");
    setUser2(user1);
    System.out.println(user1.getId()+" - "+user1.getName());
}
public static void setUser2(UserInfo ui) {
		ui = new UserInfo();
		ui.setId(10);
		ui.setName("修改后的名字");
	}

结果

1 - 张三
=====setUser2=====
1 - 张三

分析:

1)ui变量被初始化为user1值的拷贝,这里是一个对象的引用。

2)ui重新实例化,此时ui与user1已经不是同时引用的User对象。

3)ui调用set赋值后,修改的是新的对象,此时User并没有被修改。

4)方法结束后,ui变量不再使用,被释放,而user还是没有变,依然指向User对象。

结论:当传递方法参数类型为引用数据类型时,参数重新实例化,则修改的是新的对象的值。


2.3内部方法2个对象互换对象引用,这外部被引用的对象值变了

public static void main(String[] args) {
    UserInfo user1 = new UserInfo();
    UserInfo user2 = new UserInfo();
    user1 = new UserInfo();
    user1.setId(1);
    user1.setName("张三1");
    user2 = new UserInfo();
    user2.setId(2);
    user2.setName("张三2");
    System.out.println("=====copyUser4=====");
    System.out.println("user1: "+user1.getId()+" - "+user1.getName());
    System.out.println("user2: "+user2.getId()+" - "+user2.getName());
    copyUser4(user1, user2);
    System.out.println("user1: "+user1.getId()+" - "+user1.getName());
    System.out.println("user2: "+user2.getId()+" - "+user2.getName());
}
public static void copyUser4(UserInfo ui1,UserInfo ui2) {
    UserInfo tmp = ui2;
    ui2 = ui1;
    ui1 = tmp;
    ui1.setId(200);
    ui1.setName("李四");
    ui2.setId(300);
    ui2.setName("王五");
    System.out.println("ui1: "+ui1.getId()+" - "+ui1.getName());
    System.out.println("ui2: "+ui2.getId()+" - "+ui2.getName());
}

结果

=====copyUser4=====
user1: 1 - 张三1
user2: 2 - 张三2
ui1: 200 - 李四
ui2: 300 - 王五
user1: 300 - 王五
user2: 200 - 李四

分析:

1)ui1变量被初始化为user1值的拷贝,ui2变量被初始化为user2值的拷贝。

2)ui1重新指向user2,ui2重新指向user1。

3)ui1调用set赋值后,修改的是user2的值;ui2调用set赋值后,修改的是user1的值。

4)方法结束后,ui1和ui2变量不再使用,被释放,而user1(被ui2修改)和user2(被ui1修改)被响应修改。

结论:当传递方法参数类型为引用数据类型时,参数重新指向其他对象时,则修改的是新的对象的值。

参照下图

image.png

这是加粗的文字 这是倾斜的文字 这是斜体加粗的文字

厉害

厉害X2

厉害X3

请输入有意义的内容,最多1000字,切勿灌水!博主将保留删除评论的权力![]~( ̄▽ ̄)~*

请输入有意义的内容,最多1000字,切勿灌水!博主将保留删除评论的权力![]~( ̄▽ ̄)~* 请输入有意义的内容,最多1000字,切勿灌水!博主将保留删除评论的权力![]~( ̄▽ ̄)~* 请输入有意义的内容,最多1000字,切勿灌水!博主将保留删除评论的权力![]~( ̄▽ ̄)~* 请输入有意义的内容,最多1000字,切勿灌水!博主将保留删除评论的权力![]~( ̄▽ ̄)~* 请输入有意义的内容,最多1000字,切勿灌水!博主将保留删除评论的权力![]~( ̄▽ ̄)~* 请输入有意义的内容,最多1000字,切勿灌水!博主将保留删除评论的权力![]~( ̄▽ ̄)~* 请输入有意义的内容,最多1000字,切勿灌水!博主将保留删除评论的权力![]~( ̄▽ ̄)~* 请输入有意义的内容,最多1000字,切勿灌水!博主将保留删除评论的权力![]~( ̄▽ ̄)~*

啊啊啊 啊 啊啊啊啊 啊 啊 啊 啊啊啊啊 啊 啊 啊 啊啊啊啊 啊 啊 啊 啊啊啊啊 啊 啊 啊 啊啊啊啊 啊 啊 啊 啊啊啊啊 啊 啊 啊 啊啊啊啊 啊 啊 啊 啊啊啊啊 啊 啊 啊 啊啊啊啊 啊 啊 啊 啊 啊 啊 啊

啊 啊 啊 啊 啊

{context}