A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王红潮 中级黑马   /  2012-9-6 18:52  /  1904 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 王红潮 于 2012-9-7 00:27 编辑
  1. class Test
  2. {
  3. public static void main(String[] args)
  4. {
  5. int i = 0;
  6. test(i);
  7. System.out.println(i);//<FONT color=red>为什么这里i==0,而下面的那个程序里a[0]==1?</FONT>
  8. }
  9. public static void test(int i)
  10. {
  11. i++;
  12. }
  13. }


  14. public class Test
  15. {
  16. public static void main(String[] args)
  17. {
  18. int[] a=new int[1];
  19. test(a);
  20. System.out.println(a[0]);//结果为1
  21. }
  22. public static void test(int[] a)
  23. {
  24. a[0]++;
  25. }
  26. }
复制代码
不都是函数里面的局部变量吗?为什么结果不一样呢?

7 个回复

倒序浏览
本帖最后由 武庆东 于 2012-9-6 19:58 编辑

    class Test
    {
    public static void main(String[] args)
    {
    int i = 0;
    test(i);//调用该方法结束后,i++是地址向下内存中的地址向下移动一位,但是i的值仍然为0
    System.out.println(i);
    }
    public static void test(int i)
    {
    i++;
    }
    }


    public class Test
    {
    public static void main(String[] args)
    {
    int[] a=new int[1];
    test(a);//a数组的默认的元素均为0,运行玩该方法后,a[0]中的值加1所以,a[0]指向的值为0
    System.out.println(a[0]);
    }
    public static void test(int[] a)
    {
    a[0]++;
    }
    }
回复 使用道具 举报
"为什么这里i==0,而下面的那个程序里a[0]==1?"

因为上面的test()方法中的参数是传入一个int型变量,而int的基本数据类型,在一个方法中是无法修改参数中为基本数据类型的值的.
下面的test()方法中是要求传入一个int型数组,而数组是引用类型数据,在方法中的是可以修改参数中为引用类型数据的值的.
回复 使用道具 举报
这里是涉及到了值传递和引用传递,int是基本数据类型,是按值传递的,实际上是将参数的值作了一个拷贝传进方法的,那么在方法函数里再怎么改变其值,其结果都是只改变了拷贝的值,而不是原值,所以i的值是不变的。打个比方,我只是给了别人一个和我一模一样的东西,他再怎么改变它也是改变的是他的那个,我的还在我的手里,他改变不了。
而第二个程序中参数是数组,是引用数据类型,作为参数,是按引用传递的,就像是我把一个东西得使用权交给你,所以你要是改变它,还给我的时候他就变成你改变后他的样子了。
你看看下面这个例子,体会一下值传递:
  1. public  class  Demo1{
  2.     public static void exchange(int a, int b){
  3.         int temp = a;
  4.         a = b;
  5.         b = temp;
  6.     }
  7.     public static void main(String[] args){
  8.        int a = 10;
  9.        int b = 100;
  10.        exchange(a, b);     
  11.            //调用后
  12.        System.out.println("a="+a);
  13.           System.out.println("b="+b);
  14.     }
  15. }
复制代码
回复 使用道具 举报
简单点说就是java的值传递和引用传递的区别
你的第一个程序传递的是基本数据类型。java使用值传递方式。在方法中的变量只是原变量的一个拷贝,方法中对数据的操作并不影响原数据。
你的第二个程序传递的是引用数据类型(数组是引用类型,)。java使用引用传递的方式,也就是传递的是对象的内存地址。方法中的变量指向的依然是原对象,对该变量的操作将影响到原对象。
所以看到了两个不一样的结果。
回复 使用道具 举报
在java中

基本数据类型传递的是值。
引用数据类型传递的是在内存中的地址。

因此在方法里如果改变两个数据的话
基本数据类型是不会改变的(因为在内存中它指向的数据的地址没改变,所以不会发生改变)
所以在第一段代码中i的值没有变化,改变的只是形式参数

引用数据类型如果改变的话,它改变的是地址指向的堆中的数据。所以方法结束后也会改变
所以第二段代码结果改变了
回复 使用道具 举报
01.class Test

02.{

03.public static void main(String[] args)

04.{

05.int i = 0;//对a进行赋值为0,局部变量

06.test(i);//这里相当于将局部变量i=0,复制一份给了test(i)方法中的i,并没有改变5行中i的值.改变的是方法test(i)中的局部变量i,
                        //如果把test(i)写成test(n),这样就不会被变量的名字混淆了;

07.System.out.println(i);//这里打印的i是main方法的局部变量i,由于i并没有改变,所以打印的是0

08.}

09.public static void test(int i)//这里传入的是int类型的10,并不是变量i,改变的是test方法中的局部变量i而已

10.{

11.i++;

12.}

13.}

14.

15.

16.public class Test

17.{

18.public static void main(String[] args)

19.{

20.int[] a=new int[1]; //定义数组,数组是引用类型,new int[1]会在堆内存中开辟空间,而int[] a 则存在栈内存中,a为new int[i]的引用,即a存的是数组对象的地址.

21.test(a); //将数组a传入方法test(int[] a)中,相当于test方法中的int[]型局部变量a得到了数组对象new int[1]的地址值,然后也指向了这个对象

22.System.out.println(a[0]);//所以,此处访问对象的第一个元素,已经做了一次自增操作,即为1

23.}

24.public static void test(int[] a)//test方法中的局部变量a得到了数组对象的地址值,做a[0]++时,是对new int[1]对象中的第一个元素进行了改变

25.{

26.a[0]++;

27.}

28.}

第二种情况中,main方法中的变量和test方法中的变量都指向了同一个数组对象,所以调用test(a)方法改变了该数组对象中元素的值后,main方法输出的也是改变后的值,嘿,刚刚学会的
回复 使用道具 举报
陈莹 发表于 2012-9-6 19:35
这里是涉及到了值传递和引用传递,int是基本数据类型,是按值传递的,实际上是将参数的值作了一个拷贝传进 ...

写的很清楚,终于明白了,谢谢啊!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马