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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

class Test {
        public static void main(String[] args) {
                int a = 10;
                int b = 20;
                System.out.println("a:"+a+",b:"+b);               
                change(a,b);
                System.out.println("a:"+a+",b:"+b);                        //此语句输出结果为:a=10;b=20;

                int[] arr = {1,2,3,4,5};
                change(arr);
                System.out.println(arr[1]);                                      //次语句输出的是:4
        }

        public static void change(int a,int b) {       
                System.out.println("a:"+a+",b:"+b);               
                a = b;                                                                       
                b = a + b;                                                               
                System.out.println("a:"+a+",b:"+b);               
        }

        public static void change(int[] arr) {               
                for(int x=0; x<arr.length; x++) {
                        if(arr[x]%2==0) {
                                arr[x]*=2;
                        }
                }
        }
}
以上两条输出语句实在不解,为什么一个语句经过调用函数后数值不变,另一个经过调用后数值却改变了?请大神赐教

17 个回复

倒序浏览
同求赐教
回复 使用道具 举报
int等基本数据类型变量作为方法调用的参数时是把它的值拷贝一份,其本身并没有改变,方法内部改变的只是那一份拷贝。而数组等引用数据类型变量则不同,它本身存的是对象的引用(地址),传递给方法 时,把引用拷贝一份传给方法,java中只要有了引用就能操作对象,所以后面的调用数值改变,因为那个数组从始至终都只有一份,引用到是产生了2份。
回复 使用道具 举报
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!看不懂
回复 使用道具 举报
孤单背影 来自手机 中级黑马 2015-10-23 00:29:26
报纸
内存有块区域叫栈,方法都在里面运行;还有一块区域叫堆,引用类型(数组)在里面,栈里的主方法会对数组有一个指向(地址)。当基本数据类型执行时是在栈里面再开一块内存运行而不是在主方法里,执行完毕没有返回任何值,然后就会弹栈死亡。而当改变数组时,因为指向地址没变所以找到的就是改变后的数组。
回复 使用道具 举报
同学,画图理解吧   不要吝啬自己的绘画技术   
栈调用方法后就扔掉了,没有返回值并且没有在main函数中赋值,调用的方法得出的值不会覆盖main函数原有的值。  
回复 使用道具 举报
参数传递有两种形式:
1.值传递:
(1)基本类型作为参数传递时,传递的是这个值的拷贝,无论怎样改变这个拷贝,原值是不会变的。
(2)内存解析:当执行int a=10,int b=20后,程序在栈内存开辟一块地值为AD8500,AD8501的内存,里面分别存放10和20,;当执行change()方法时,程序在栈中有开辟一块地址为AD8600,AD8601的内存,将a,b的值传递进来,这时a=10,b=20,执行完a=b,b=a+b后,AD8600,AD8601的值分别为20,30,在该过程中,分别存放a,b所对应的内存没有任何关系,函数调用结束后,内存给chang()函数分配的内存被垃圾回收器回收,而主函数中的值并未变化,即地址AD8500,AD8501的值始终没有变化。
2.对象传递(引用传递):
(1)当对象作为参数传递时,传递的是对象的引用,即对象的地址。
(2)内存解析:当程序执行完int[] arr={1,2,,3,4,5}程序在栈内存中开辟一块编号为AD9500的内存空间用于存放arr[0]的引用地址,里面存放的是堆内存的一块地址(假定为BE2500),可以理解为有一个指针指向了堆内存中编号为BE2500的地址,堆内存编号为BE2500的这个地址存放的才是array[0]的值。---当程序进入change方法后,将arr的值,也就是对象的引用BE2500传了进来。这时,这时,程序在栈内存又开辟了一块编号为AD9600的内存空间,里面存放的值为BE2500,也可以理解为栈内存编号为AD9600的内存中有一个指针,也指向了堆内存中编号为BE2500的内存地址。---这样一来,栈内存AD9500,AD9600都指向了堆内存编号为BE2500的内存地址,执行完chang方法时,数组中的值得到改变,但在堆内存中的地址值不变,调用结束后,编号AD9500仍指向编号为BE2500的堆内存空间,所以打印结果为4.

  
回复 使用道具 举报
syb012 中级黑马 2015-10-23 07:59:20
8#
真是特别棒,是参数传递方式的不同
回复 使用道具 举报
就是改的值不是它自身,只是它的一个副本而已,对于本身而言,没有任何变化
回复 使用道具 举报
费斯 中级黑马 2015-10-23 16:26:12
10#
又学到了!看来要常来啊
回复 使用道具 举报
一个是在栈内存中局部变量,第一个函数执行完后函数里的变量释放,作用域是函数中,而数组是在堆内存中的,随着对象的产生而产生,生命周期和对象一致,作用在整个类中。
回复 使用道具 举报
可以学到新东西
回复 使用道具 举报
会盟天下英豪 发表于 2015-10-23 04:02
参数传递有两种形式:
1.值传递:
(1)基本类型作为参数传递时,传递的是这个值的拷贝,无论怎样改变这个 ...

很详细啊,多谢指教
回复 使用道具 举报
高手真多。。。
回复 使用道具 举报
lixp 中级黑马 2015-10-27 19:09:59
15#
看起来跟C的指针好像啊
回复 使用道具 举报
学习了!
回复 使用道具 举报
ppaapc 中级黑马 2015-10-28 20:03:23
17#
高手真多  学习了
回复 使用道具 举报
7楼很厉害
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马