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:还没有写完,正在上班时间,晚上再写吧!

如有错误,请大家帮忙纠正一下。

 

posted @ 2015-09-08 09:26  邻家小书童  阅读(931)  评论(5编辑  收藏  举报