被问懵的java值传递和引用传递 java到底是值传递还是引

java到底是值传递还是引用传递

悲惨的起因

为什么悲惨呢,因为尽管我看了多少篇讲java值传递还是引用传递的文章在面试的时候还是被面试官干碎了,十分的悲惨。
xinlei

所以下定决心痛定思痛,写这篇博客。。。

问题的关键

我觉得要弄明白java是值传递还是引用传递,首先要弄明白什么事值传递什么事引用传递。引用百度百科的概念介绍

  • 值传递

值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

  • 引用传递

引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

从百度百科的描述中我们可以看出值传递与引用传递表现出来的一大区别是是否传入函数后,在函数中操作会影响实际参数。而对于Java来说能够传入方法中的值分为两种,一种是基本数据类型,如int,double,long等,另一种是引用类型,如String,或者自定义的类等。所以要分析Java是值传递还是引用传递要从两个方面区分入手。

基本数据类型的传递方式

对于基本数据类型的传递方式,首先我们先来看一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
java复制代码public class TestRunTime {

public static void main(String[] args) {
int i = 3;
TestRunTime test = new TestRunTime();
test.exchange(i);
System.out.println(i);
}

public void exchange(int x){
x = 5;
}
}

对于这个例子,最后输出的结果为3,方法中的改变并没有影响到原值。对于这个情况我们应该从基本数据类型中的值存储的方式来思考,对于基本数据类型,值直接保存在变量中而且对于这样一个局部变量来说,它存在于局部变量表中。但是基本数据类型也要看存在位置,当你数据局部变量的时候,方法中的操作是无法影响到这个变量的,传值过程也是值的拷贝而已。

引用类型的传递方式

对于引用类型的传递方式,首先我们要明确的是我们创建的对象会存储在堆中,而栈中保存的是堆内地址,情况如下。我们创建对象的过程实际上是在栈中创建一个对象,存放堆中对象的地址,在堆中创建一个对象,存放实际的内容。

duixiangcunfang

当我们把对象作为参数传入方法时,过程是将对象的地址拷贝了一份,即形参指向了堆内实参的地址,这时候问题就来了,如果我们在方法中对对象作出修改,我们会发现方法外的实参内容变了,就会认为这是引用传递,但实际上是不对的,这是概念的混淆,我们再来看一下定义,引用传递和值传递的区别在是否对传入参数做出修改,而我们传入方法中的是实参的地址,我们的操作并未影响到实参,而我们改变形参的引用时,同样实参的引用也不会发生变化。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码public static void main(String[] args) {
Test test = new Test();
User user = new User();
System.out.println("操作之前的"+user);
test.work(user);
System.out.println("操作之后的"+user);
}


public void work(User user){
user = new User();
}

image-20210911181800623

如图结果所示,我们可以看到,在方法中对形参的地址修改并未影响到实参,所以java是值传递而非引用传递。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%