java——值传递和引用传递
值传递
? 先来看个例子: public static void valueCross(int age,float weight) { System.out.println("传入的age值:"+age); System.out.println("传入的weight值:"+weight); age=23; weight=60; System.out.println("修改后的age值:"+age); System.out.println("修改后的weight值:"+weight); } public static void main(String[] args) { int age=10; int weight=50; valueCross(age,weight); System.out.println("方法执行后的age:"+age); System.out.println("方法执行后的weight:"+weight); }
运行结果: 传入的age值:10 传入的weight值:50.0 修改后的age值:23 修改后的weight值:60.0 方法执行后的age:10 方法执行后的weight:50
我们可以看到valueCross方法执行后,实参age和weight的值并没有发生变化,这是什么原因? 首先程序运行时,先从main方法开始执行,此时JVM为main()方法往虚拟机栈中压入一个栈帧,即为当前栈帧,用来存放main()中的局部变量表(包括参数)、操作栈、方法出口等信息,如a和w都是mian()方法中的局部变量,因此可以断定,age和weight是躺着mian方法所在的栈帧中 接着调用valueCross方法,此时JVM为valueCross()方法往虚拟机中压入一个栈帧,即为当前栈帧,用于存放valueCross方法的局部变量等信息;因此age和weight是躺着valueCrossTest方法所在的栈帧中,而他们的值是从a和w的值copy了一份副本而得,如图: 因此这两个age和weight对应的内容不是同一个,在valueCross方法中修改的只是自己栈中的内容,并没有修改main方法栈中的内容 ? 引用传递
? ?先有一个Person类代码如下: public class Person { private String name; private int 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; } }
?测试类代码: public class TestArr { public static void PersonCross(Person person) { System.out.println("传入的person的name:"+person.getName()); person.setName("敖丙"); System.out.println("方法内重新赋值后的name:"+person.getName()); } public static void main(String[] args) { Person p=new Person(); p.setName("哪吒"); p.setAge(4); PersonCross(p); System.out.println("方法执行后的name:"+p.getName()); } }
测试结果1: 传入的person的name:哪吒 方法内重新赋值后的name:敖丙 方法执行后的name:敖丙
我们可以看到PersonCross方法执行后,person的name值被改变了 ? 下面再看一段代码: public class TestArr { public static void PersonCross(Person person) { System.out.println("传入的person的name:"+person.getName()); person=new Person();//新添加的代码 person.setName("敖丙"); System.out.println("方法内重新赋值后的name:"+person.getName()); } public static void main(String[] args) { Person p=new Person(); p.setName("哪吒"); p.setAge(4); PersonCross(p); System.out.println("方法执行后的name:"+p.getName()); } }
测试结果2: 传入的person的name:哪吒 方法内重新赋值后的name:敖丙 方法执行后的name:哪吒
有没有发现什么不同,这次PersonCross方法执行后person的name值并没有改变,这又是为什么? 我们知道,java中的对象和数组是存放在堆内存中的,而堆内存是线程共享的,所以main方法执行时,会在堆内存中开辟一块内存,用来存储p对象的所有内容,然后再栈内存中创建一个引用p存储堆区中p对象的真实地址,如下图: 当执行到PersonCross方法时,因为方法内有这么一行代码:person=new?Person(),此时JVM在堆内存中又开辟了一块内存空间,假设地址为xo2222,那么现在的person则指向了xo2222这块内存,现在修改person的name值修改的是xo2222这块内存空间的值,不会改变xo3333的值,所以测试结果2中的name没有发生变化?? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |