티스토리 뷰

 최근에 자바 언어 공부를 리마인드할 필요가 있어서 하루 이틀 인프런 강의를 빠르게 듣다가, 예전에 흥미롭게 한 공부한 부분이 있어 여기 올려보고자 한다. 자바의 배열과 메모리 주소에 관한 부분인데 학과 시험에서 기초 부분을 다룰 때 나왔었던 부분이기도 할 뿐더러 제대로 짚고 넘어가지 않으면 나중에 배열을 다룰 때 헷갈리는 부분이다. 그만큼 중요한 기초 부분이어서 간단하게 정리해보고자 이 글을 적었다.

import java.util.Arrays;

public class MainClass {
	public static void main(String[] args) {
		int[] arr1 = new int[3];
		
		arr1[0] = 100;
		arr1[1] = 200;
		arr1[2] = 300;
		
		System.out.printf("arr1[0] : %d\n", arr1[0]);
		System.out.printf("arr1[1] : %d\n", arr1[1]);
		System.out.printf("arr1[2] : %d\n\n", arr1[2]);
	}
}

 우선 배열을 생성하고 초기화해주자. arr1 배열을 선언하고 첫번째에는 100, 두번째에는 200, 세번째에는 300의 값을 대입시켜 주었다. 그리고 각 배열에 들어간 값을 확인해보니 잘 들어간 것을 확인할 수 있었다.

		int[] arr1 = new int[3];
        
		arr1[0] = 100;
		arr1[1] = 200;
		arr1[2] = 300;
		
		System.out.println("arr1 : " + Arrays.toString(arr1));
		
		int[] arr2 = null;
		arr2 = Arrays.copyOf(arr1, arr1.length);
		System.out.println("arr2 : " + Arrays.toString(arr2));

 배열에 값을 넣는 방법은 일일히 초기화하면서 넣어주는 방법 말고도 다른 배열에 있는 값을 가져오는 방법도 있다. Arrays.copyOf() 메소드를 사용하면 다른 배열에 있는 값을 복사해올 수 있다. 사용하는 방법은 아래와 같다.

 

[복사한 값을 저장하는 배열] = Arrays.copyOf([복사할 배열], [복사할 배열].length);

 

 그리고 배열 안에 들어있는 값을 보기 위해서 배열의 전체 값을 한 번에 출력하는 메소드를 사용해보자.

 

Arrays.toString([출력하고자 하는 배열]);

 

 그러면 arr1 배열과 arr2 배열에 들어있는 값들을 확인할 수 있는데 arr1에 들어있는 값들을 arr2으로 복사했으므로 두 배열 안에 들어있는 값들이 같은 것을 알 수가 있다.

		int[] arr3 = null;
		arr3 = arr1;
		
		System.out.println("arr3 : " + Arrays.toString(arr3));

 그런데 Arrays.copyOf() 메소드를 사용하지 않고 배열을 복사하는 다른 방법이 또 있다. 그냥 '=' 기호를 사용해서 복사할 배열을 붙여넣고자 하는 배열에 넣어버리는 것이다. 내가 만든 코드에서는 arr3 배열을 새로 만들어서 null로 지정한 후 arr1을 넣었다.

 그리고 배열을 출력해보면 arr1에 있는 배열의 값과 동일하게 arr3 안에 있는 값들이 출력된다. 그렇다면 굳이 손아프게 Arrays.copyOf() 메소드를 사용하여 배열을 복사할 필요없이 '=' 기호를 사용하여 배열을 복사하면 되지 않는가? 라는 생각을 할 수 있다. 하지만 겉보기에만 내용이 같아보이는 것일뿐 메모리 주소가 다르게 지정된다는 큰 차이점이 있다.

		int[] arr1 = {100, 200, 300};
		System.out.println("arr1 : " + arr1);
		
		int[] arr4 = {100, 200, 300};
		System.out.println("arr4 : " + arr4);

 배열은 배열의 첫번째 항목인 배열[0]의 시작 주소가 배열 전체의 시작 주소와 동일하다. 배열의 몇번째 항목을 출력할 지 정하지 않고 그냥 배열의 이름만 넣어서 출력하면 메모리 주소를 확인할 수 있는데, 이것이 배열이 가리키는 첫번째 항목의 주소이다.

 

 위 예시 코드에서 arr1와 arr4는 같은 배열 내용을 가지고 있지만 저장되는 메모리 주소는 다르다. 즉, 내용물이 같다고 해서 같은 배열이라고 볼 수 없다는 것이다. arr1과 arr4는 이름만 다를 뿐 아니라 해당 배열이 가지고 있는 내용물이 저장된 장소도 다르다고 보면 된다.

		int[] arr1 = {100, 200, 300};
		System.out.println("arr1 : " + arr1);
		
		int[] arr2 = null;
		System.out.println("arr2 : " + arr2);
        
		arr2 = Arrays.copyOf(arr1, arr1.length);
		System.out.println("arr2 : " + arr2);

 이제 배열을 복사하면 메모리 주소에 무슨 일이 벌어지는지 살펴보자. arr1은 새로 선언한 것이 아니라 위에서 계속 사용한 arr1을 그대로 사용하고 있다. 그래서 내용물도 같고 메모리 주소도 똑같다. arr2는 처음에 null로 지정하였다. 즉, arr2가 가리키는 배열의 주소는 null로 아무것도 가리키지 않는다는 것이다. 여기서 메모리 주소를 출력해보면 arr2의 메모리 주소가 null로 나옴을 확인할 수 있다.

 

 다음에는 arr2에 Arrays.copyOf() 메소드를 사용하여 값을 복사한 뒤 메모리 주소값을 확인해보자. arr1과 arr2 안에 있는 내용물은 복사가 되어 같지만, arr2의 메모리 주소는 다르게 나온다. 복사된 내용물이 다른 메모리 주소로 복사된 것이다. 우리가 흔히 말하는 '복사'의 개념과 일치한다. 같은 내용물이 다른 장소에 존재하게 된 것이다.

		arr2[0] = 400;
		System.out.println("arr1 : " + Arrays.toString(arr1));
		System.out.println("arr2 : " + Arrays.toString(arr2));

 같은 내용물이 다른 장소에 존재함으로 인해서 생기는 특징은 서로 영향을 받지 않는다는 것이다. 당연한 이야기겠지만 서로 다른 장소에 내용물이 저장된 것이기 때문에 arr2의 내용물을 바꾸어도 arr1의 내용물에는 아무런 영향이 없다. 위 예시코드에서는 arr2의 첫번째 항목에 400을 넣었고, 출력해보니 arr2의 내용물만 바뀐 것을 확인할 수 있다.

		int[] arr3 = null;
		arr3 = arr1;
		System.out.println("arr3 : " + arr3);

 반면에 '=' 기호 같은 배정 연산자를 사용하여 배열을 복사해버리면 어떤 일이 벌어질까? 우선 메모리 주소부터 확인해보자. 이게 웬걸? 메모리 주소가 똑같이 나온다. 이것은 arr1이 가리키는 배열과 arr3이 가리키는 배열이 동일하다는 것을 의미한다.

		arr3[0] = 400;
		System.out.println("arr1 : " + Arrays.toString(arr1));
		System.out.println("arr3 : " + Arrays.toString(arr3));

 가리키는 배열이 같기 때문에, 가리키는 내용물이 같기 때문에 복사받은 arr3의 내용물만 바꿔도 arr1의 출력내용까지 같이 바뀌게 된다. 즉, '=' 기호 배정 연산자를 사용하여 배열을 복사하면 내용물이 복사되는 것이 아니라 메모리 주소가 복사된다는 사실을 알 수 있다.

 

 처음에 이런 메모리 주소에 대한 개념을 머리에 싣고 가지 않으면 나중에 코딩을 하는 데에 있어 예상치 못한 결과를 맞닥뜨릴 수 있다. 위의 코드들은 메모리 주소에 대한 개념을 공부 초기에 쉽게 이해할 수 있는 좋은 예시라고 생각되어서 입문 단계에 있는 분들이 읽고 도움이 되었으면 좋겠다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함