Java参数按值传递?按引用传递
有时候在想,java在调用方法时候究竟是按值传递还是按引用传递,之前有人说是基本数据类型按值传递,引用类型按引用传递。一时间,似乎都有道理。
笔者在此不追究字眼上的辨别识字能力,把自己对这个问题的理解阐述一下,笔者不想说这是按值传递还是按引用传递,自己理解就好了吧,毕竟java会用才是王道。
先看一下下面的代码:
1 package shb.java.testmemory; 2 3 public class TestMeo { 4 5 /**测试基本数据类型以及引用类型参数按值传递 6 * @Description: 7 * @author shaobn 8 * @param args 9 * @Date:2015-9-8 上午7:53:56 10 */ 11 public static void main(String[] args) { 12 // TODO Auto-generated method stub 13 testInt(); 14 testStr(); 15 testPack(); 16 testObj(); 17 testObj_2(); 18 } 19 //NO1.测试基本数据类型 20 public static void testInt(){ 21 int num1 = 12; 22 System.out.println("Before change::"+num1); 23 changeInt(num1); 24 System.out.println("After change::"+num1); 25 } 26 //测试字符串类型 27 public static void testStr(){ 28 String str = "helloworld"; 29 System.out.println("Before change::"+str); 30 changeStr(str); 31 System.out.println("After change::"+str); 32 33 } 34 //测试包装类型 35 public static void testPack(){ 36 Integer integer = new Integer(42); 37 System.out.println("Before change::"+integer); 38 changePack(integer); 39 System.out.println("After change::"+integer); 40 } 41 //测试引用类型 42 public static void testObj(){ 43 Person person = new Person(); 44 System.out.println("Before change::"+person.age); 45 changeObj(person); 46 System.out.println("After change::"+person.age); 47 } 48 //测试引用类型方式二 49 public static void testObj_2(){ 50 Person person = new Person(); 51 System.out.println("Before change::"+person.age); 52 changeObj_2(person); 53 System.out.println("After change::"+person.age); 54 } 55 public static void changeInt(int num){ 56 num = 21; 57 } 58 public static void changeStr(String str){ 59 str = "hellobeijing"; 60 } 61 public static void changePack(Integer integer){ 62 integer = new Integer(89); 63 } 64 public static void changeObj(Person person){ 65 person.age = 87; 66 } 67 public static void changeObj_2(Person person){ 68 person = new Person(); 69 person.age = 78; 70 } 71 } 72 //引用类型测试类 73 class Person{ 74 public int age = 78; 75 }
Look NO1:
说明一下:笔者在上面画的两张图着实不咋样,只能做到这种程度了。我们分析一下:当数据为基本数据类型时,我们传给形参的仅仅是一个实参的副本(Copy),当然由于栈内存变量共享的特征,这两个变量共同指向此变量值。
当我们对形参进行改变时,首先,在栈内存中会寻找是否存在新的变量值,如果有,则指向新的变量值(体现栈内存数据共享的特点)。如果没有的话,在栈内存中回开辟一块空间,存储新的变量值,同时形参变量会指向新的变量值。
此时我们发现,这时的变量值已经与实参的变量没有关系,两个独立的变量。所以经过函数后改变的变量值与之前的没有关系,故输出的还是之前的变量值。
另外,我们看到,当传递对象的引用时,person引用变量中存储的是Person对象在堆内存中的内存地址,所以传递的是内存地址(笔者理解为是一串数字)。此时两个形参变量是有共同的内存地址值,所以指向同一个内存对象。我们观察
发现,当我们改变对象中的属性值时,有牵一发而动全身的感觉,只要你改变这个对象,这个对象就被改变,而不存在另外开辟一个对象的概念(String类型和包装类型除外)。
PS:还没有写完,正在上班时间,晚上再写吧!
如有错误,请大家帮忙纠正一下。
吾宁做一叶扁舟,始航于湖边,遨游于海上,浪迹于江中。