java中值传递_Java中的值传递和引用传递

本文详细探讨了Java中的参数传递机制,解释了基本类型和引用类型在方法调用时的区别。对于基本类型,参数传递是值传递,方法内无法改变原始变量值;而对于引用类型,虽然看起来像是引用传递,但实际上仍是值传递,方法内修改的是对象属性,而非引用本身。通过示例代码展示了这一概念,并分析了内存中对象引用的变化过程。
摘要由CSDN通过智能技术生成

在java中实质只存在一种传递方式:即值传递。 而引用传递是对C/C++而言的。结论:

对于基本类型,在方法体内对方法参数进行重新赋值,并不会改变原有变量的值。

对于引用类型,在方法体内对方法参数进行重新赋予引用,并不会改变原有变量所持有的引用。

方法体内对参数进行运算,不影响原有变量的值。

方法体内对参数所指向对象的属性进行运算,将改变原有变量所指向对象的属性值。

在JAVA中变量有以下两种:

基本类型变量,包括char、byte、short、int、long、float、double、boolean。

引用类型变量,包括类、接口、数组(基本类型数组和对象数组)。

最后我们得出如下的结论:

基本类型和基本类型变量被当作参数传递给方法时,是值传递。在方法实体中,无法给原变量重新赋值,也无法改变它的值。

对象和引用型变量被当作参数传递给方法时,在方法实体中,无法给原变量重新赋值,但是可以改变它所指向对象的属性。

2 public class Person

3 {

4   private String name = null;

5   private int age = 0;

6

7   public Person(String name, int age) {

8     this.name = name;

9     this.age = age;

10   }

11

12   public void changeName(String newName) {

13     this.name = newName;

14   }

15

16   public void changeAge(int newAge) {

17     this.age = newAge;

18   }

19

20   public String toString() {

21     return "Person - Name: " + name + ", Age: " + age;

22   }

23 }

24

25 public class PassByValue

26 {

27   public static void main(String[] args) {

28     // one example

29     String value1 = "value1: aaa";

30     String value2 = "value2: bbb";

31

32     swapValue(value1, value2);

33

34     System.out.println(value1);

35     System.out.println(value2);

36

37     // another example

38     Person person = new Person("张三", 20);

39

40     System.out.println(person.toString());

41

42     changePerson(person);

43

44     System.out.println(person.toString());

45   }

46

47   public static void swapValue(String tmpValue1, String tmpValue2) {

48     String tempStr = tmpValue1;

49     tmpValue1 = tmpValue2;

50     tmpValue2 = tempStr;

51   }

52

53   public static void changePerson(Person tmpPerson) {

54     tmpPerson.changeName("李四");

55     tmpPerson.changeAge(30);

56   }

57 }

58

考虑一下上面这段代码的输出结果是什么?

我相信绝大多数人都能快速的给出正确答案:

value1: aaa

value2: bbb

Person - Name: 张三, Age: 20

Person - Name: 李四, Age: 30

答案为什么是这样的呢?那么 Java 到底是按值传递还是按引用传递参数的呢?

例 子1中的 swapValue() 方法不起作用,看起来是按值传递参数的,例子2中的 changeName() 和 changeAge() 方法起作用,从表面上看起来好像又是按引用传递参数的。呵呵,别急,先让我们来弄清楚一个重要的概念,就是 Java 操纵对象都是通过引用来实现的,所有的对象变量都是所指向的对象的引用,那也就是说所有对象变量的值并不是它所指向的对象本身,而是该对象的引用,这句话听起来可能有点让人犯晕,举个例子来说,String str = new String("aaa"); 这条语句的意思是 new 了一个值为 "aaa" 的字符串对象,然后用一个名字叫 str 的对象变量来指向它,保存它的引用,假设在内存中 new 出来的这个字符串对象的实际地址为 0xA242, 那么 str 的值实际上是 0xA242。

现在来看看例子1,假设

String value1 = "value1: aaa" 的地址为 0xA242,

String value2 = "value2: bbb" 的地址为 0xA24B,

然 我们来看看 swapValue(value1, value2); 语句 Java 是怎么执行的。当程序执行到这句语句的时候,JVM 在栈中创建两个临时变量 tmpValue1,tmpValue2,用来接收传进来的 value1 和 value2 的值,而 value1 和 value2 的值分别为 0xA242 和 0xA24B,所以那两个临时变量 tmpValue1和tmpValue2 的值也被赋值为 0xA242 和 0xA24B,此时接下来的三条语句分别是

tempStr = 0xA242,

tmpValue1 = 0xA24B,

tmpValue2 = 0xA242;

此时 tmpValue1 的值是指向 "value2: bbb" 这个对象的,

tmpValue2 的值是指向 "value1: aaa" 这个对象,你可以在 swapValue() 方法内部打印 tmpValue1 和 tmpValue2 的值验证一下。

不 过这里的 tmpValue1和tmpValue2 是在栈中的临时变量,而并不是 main 方法中 value1和value2,main 方法中 value1和value2 的值并没有改变,那这里所谓的值传递是指什么呢?因为 value1 的值是 0xA242("value1: aaa" 这个对象的引用),而并不是 "value1: aaa" 这个对象,传递参数时传递的是 "value1: aaa" 这个对象的引用也就是 value1 的值,所以是值传递。

例子2也是一样的,假设

Person person = new Person("张三", 20) 的地址为 0xA242,

那 么 person 的值是 0xA242, 那么通过调用 changePerson(person); 将 0xA242 传递给 tmpPerson, 也就是 tmpPerson 此时的值为 0xA242 也就是 new Person("张三", 20) 这个对象的引用,也就是说 tmpPerson 指向 new Person("张三", 20) 对象,对 tmpPerson 引用对象的修改实际上就是对 person 引用对象的修改,这看起来很想引用传递的概念,但实际上是值传递,为什么呢?因为在参数传递过程中传递的是 person 的值,也就是 0xA242。

呵呵,好好体会吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值