今天写个JAVA程序,老是出现错误,于是单步调试了很久,真的很久,NND ,几百行的程序调试了老半天了都,结果终于被我发现问题的说在了,不过费了这么多事,原来是一个JAVA的一个细节的东西在搞鬼,我是初学JAVA,对JAVA的了解也没有那么深入,所以它的特性也么有掌握好,不过今天被这些细节的东西整惨了。
大家都知道,在C 和C++中,数组是不能直接被赋值的,假设有两个数组 a[10],b[10],在C和C++中是不能以 a=b的方式把b中的内容赋值给相应的数组a的,因为a和b的值其实就是该数组的头指针指向的地址,当然如果很了解数组的实现原理的话,这就很好理解了,在《数据结果》的可能中有涉及到,总之知道数据的数组名就是数组的头指针指向的***元素的地址,如果能这样理解的话,那么用大腿想一下就知道a=b是不能实现数组的赋值的,一般在C和C++中我们采用了一个循环来单个赋值,类似这样的:
- for(int i=0;i<10;i++)
- a[i]=b[i];
方式来实现,学了这么久的C和C++,用的多了,也不觉得费事。但是在JAVA中却不想C和C++一样,JAVA 很聪明,它可以使用 a=b 的方式来将b 赋值给a,这里的赋值要注意了,在JAVA中使用 a=b 的时候,在 a 中以数组的方式来输出内容的时候,跟b 的内容一模一样,说明这样的方式可行,我的程序里面就是这样用的,结果整出了BUG来了。一开始发现不管是用 a=b 还是用 a=a.clone(); 结果都是一样,有些不解,不过现在我完全清楚了。为了说明这个问题,以一段程序演示一下:
- private int[] subResources(int[] aa, int[] bb)
- {
- // 做减法
- int []a=aa;
- int []b=bb;
- for (int i = 0; i < a.length; i++)
- a[i] = a[i] - b[i];
- return a;
- }
这是用来实现两个数组想减的函数,在调用的程序中这样使用
- int []allo=pcb0.getAllocation().clone(); //方式1
- //int []allo=pcb0.getAllocation()//方式2
- int[] allocation = this.addResources(allo, request);
上面两种方式的参数传入带来的不同结果是,当你在函数addResources 修改了传入参数的值的时候,方式1不能改原来的数据,方式2能改变原来的数据。方式1它赋值的时候是先创建一个数组的副本,再把副本来给目标数组赋值,这样副本数组的地址和原来数组的地址当然不是同一个了,这样不管你怎么改,方式1它都不会改变原来的数据,方式2则不一样,方式2它直接将数据的地址赋值给目标数据,这样两个数组不同的数组名,其实指的都是同一个地址,这样当然可以改变原来的值了。
这样分析,它有点像C++中的函数传参中的 指针和引用传值一样,由于java中都摒弃了指针,所以所有的指向关系都使用了引用类型,用C++用久了就容易犯这样的错误。不像C++中这样传值 addResources (int *a,int *b) 或者 addResources (int a[],int b[]) 。这会吃亏了,看来这辈子在这个地方就这次了,学东西还得专注一点啊,现在明白了为什么招聘会上的基础题看起来简单,却不是每个人都能答好的。