数组:相同类型的数据,在内存中连续存储。
数组的声明:
int [] a ; //栈中定义了int类型数组的引用
A [] aa ; //定义了A类型数组的应用
数组的初始化:
int [] a = {1,2,3,4,5}; //定义时初始化
A [] a = new A[3]; //对象数组定义初始化, 内部初始化全为null
A []a = { new A(1,2), new A(3,4), new A(5,6)}; //定义时初始化每个对象;
在C语言中我们知道字符串数组拷贝可以使用简单的方式strcpy(str,dest);
其他类型的数组拷贝如int 类型一般我们使用memcpy或者循环实现如下:

#include<stdio.h>
#include <memory.h>
int main(void)
{
int a[5] ={1,2,3,4,5};
int b[5] ;
int i =0 ;
memcpy(b,a,sizeof(a));
for (i = 0; i<sizeof(b)/sizeof(b[0]) ; i ++)
{
printf("%d ", b[i]);
}
printf("\n");
return 0; 
}
result: 
1 2 3 4 5
#include<stdio.h>
#include <memory.h>
int main(void)
{
 int a[5] ={1,2,3,4,5};
 int b[5] ;
 int i =0 ;
 for (i =0; i<sizeof(b)/sizeof(b[0]) && i <sizeof(a)/sizeof(a[0]) ;  i++)
 {
   b[i] = a[i];
 }
 for (i = 0; i<sizeof(b)/sizeof(b[0]) ; i ++) 
 { 
 printf("%d \n", b[i]); 
 }
 printf("\n");
 return 0; //结果同上;

java中数组拷贝也可以使用循环来实现但是明显代码较繁琐不如使用函数;
这里就介绍下System.arraycopy函数格式如下:
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);
api文档中有详细介绍这里简单介绍下:
所有类都继承自object所以 src 和dest都是object 类型;
src 源数组,dest目标数组(需要将数据拷贝到这里),
srcPos源数组从第几个位置开始拷贝
destPos拷贝到目标数组从几个位置开始 (这里的位置都是下标)
length 拷贝几个元素;
举例如下:

public class TestString 
{
 	public static void main(String [] args)
 	{
 		int  []aa = {1,2,3,4,5};
 		int [] aa1 = new int [5];
 		System.arraycopy(aa,0, aa1, 0 , aa.length);
 		aa1[2] = 100;
 		for (int i =0; i < aa.length; i ++){
   			System.out.print(aa[i]);
  		}
  		System.out.println();
  		for (int i =0; i < aa1.length; i ++){
   			System.out.print(aa1[i]); 
  		}
	}
}
结果 
1  2  3  4  5
1  2  100  4  5

java 堆内存复制 线程 java内存拷贝函数_System


内存分配情况,先在栈中创建了数组aa 然后拷贝整个数组到aa1中,在栈中给aa1也分配了同样大小的空间直接赋值拷贝

情况二 引用类型数组:

public class TestArrayCopy1
{
 public static void main(String [] args)
 {
  A []a = { new A(1,2), 
      new A(3,4), 
      new A(5,6)};
  A [] b = new A[3];
  A [] bb;
  int []aa ;
  System.arraycopy(a,0,b,0,a.length);
  b[1].i = 0;
  b[1].j = 0;
  for(int i=0; i<a.length; i++)
   	System.out.println(a[i]);    
}
class A
{
 int i;
 int j ;
 public A(int i, int j){
  	this.i = i;
  	this.j = j;
 }
 public String toString(){
  	return i+"  " + j +"  ";
 }
}
结果:
1  2   0  0   5  6

这个时候为什么改变数组中一个元素的值而之前的数组值也发生了变化呢?看内存图;

java 堆内存复制 线程 java内存拷贝函数_数组_02


当调用arraycopy函数时拷贝的只是栈中的数据,而a数组在栈中存放的只是对象a数组的引用实际的属性都是分配在堆空间,因此等于b数组拷贝了一个a数组的引用数组等于,所以绿色的线依然是指向a数组在堆中分配的内存。

那为什么第一个例子的值没有发生变化呢,原因,第一个例子中数组所有的元素都分配在栈中,没有引用类型,所以这个函数属于浅拷贝。

顺便提一句:

浅拷贝即拷贝引用而没有在堆中创建一个对象,等于一个对象有两个引用;

深拷贝:需要拷贝当前引用在堆中所指向的内容,根据这个内容创建一个新的对象(并为属性分配新的空间)。

另外在还可以用二维数组来验证:

因为二维数组存放的也是引用;

public class TestArrayCopy
{
 public static void main(String [] args)
 {
  int[][] intArray = {{1,2},{1,2,3},{3,4}};
  int[][] intArrayBak = new int[3][];
  System.arraycopy(intArray,0, intArrayBak, 0 , intArray.length );
  intArrayBak[1][1] = 100;
  for (int i=0; i< intArray.length; i++)
  {
   for (int j=0; j < intArray[i].length; j++)
   {
    System.out.print(intArray[i][j]);
   }
    System.out.println();
  }
  for (int i=0; i< intArrayBak.length; i++)
  {
   	for (int j=0; j < intArrayBak[i].length; j++)
   	{
    		System.out.print(intArrayBak[i][j]);
   	}
   	 System.out.println();
  }
  }

希望对您有所帮助,大家共同进步 !!!嘻嘻哈哈!!!