얕은 복사 - 배열 복사, 주소값 복사
깊은 복사 - 배열값 복사, 물리적 복사

int[] num1 = new int[5];
int[] num2 = new int[5];
System.out.println("num1[]: " + num1);
System.out.println("num2[]: " + num2);
System.out.println("num1 == num2" + (num1 == num2));

num1[0] = 10;
num1[1] = 20;
num1[2] = 30;
num1[3] = 40;
num1[4] = 50;
printData(num1);
printData(num2);

System.out.println("=== 배열 복사 (주소값 복사, 얕은 복사) ===");
num2 = num1;
System.out.println("num1 == num2" + (num1 == num2));

System.out.println("===배열값 복사(물리적 복사, 깊은복사(deep copy)===");
int[] num3 = new int[5];
printData("num3", num3);
System.out.println(">> num3 <--- num1 데이터 복사");
for(int i = 0; i <num3.length; i++) {
num3[i] = num1[i];
}
printData("num1", num1);
printData("num3", num3);
System.out.println("num1 == num3 : " + (num1 == num3));

num1의 값을 바꾸면 num1의 주소값을 복사한(얕은 복사) num2 배열은 값이 num1과 같이 바뀌지만, 배열값을 복사한(깊은 복사)를 한 num3은 값이 바뀌지 않는다.
배열 복사 방법들
System.array.copy
배열객체.clone()
Arrays.copyOf()
Arrays.copyOfRange()
이 방법들은 모두 원본 배열과 비교했을 때 false가 뜨기 때문에 깊은 복사임을 알 수 있다.

//arraycopy(scr, srcPos, dest, destPos, length);
//arraycopy(소스객체, 시작위치, 타겟객체, 대상시작위치, 갯수);
System.arraycopy(num3, 0, num4, 0, num1.length);
System.out.println(">> System.arraycopy 복사 후");
printData("num1", num1);
printData("num4", num4);
System.out.println("num1 == num4" + (num1 == num4));
System.out.println("===배열객체.clone()복사===");
int[] num5 = num4.clone();
printData("num4", num4);
printData("num5", num5);
System.out.println("num4 == num5 " + (num4 == num5));
System.out.println("===Arrays.copyOf(원본데이터, 갯수) 복사");
int[] num6 = Arrays.copyOf(num4, num4.length);
printData("num4", num4);
printData("num6", num6);
System.out.println("num4 == num6 " + (num4 == num6));
System.out.println("===Arrays.copyOfRange(원본데이터, 부터, 끝 이전까지) 복사");
int[] num7 = Arrays.copyOfRange(num4, 0, 5);
printData("num4", num4);
printData("num7", num7);
System.out.println("num4 == num7 " + (num4 == num7));