본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Java(자바)/Java 기본

자바 참조 데이터(Java Array, Java List) 사용간 유의 사항

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2022. 3. 21.

간단하게 살펴보는 자바에서의 참조형식 데이터 입니다.

대표적인 데이터로는 배열(Array)과 컬렉션의 리스트(list)를 들 수 있습니다.

 

이러한 참조형식의 데이터는 아래와 같은 특징을 지니고 있습니다.

* 특징

 - 참조형 변수 안에는 값들을 저장하고 있는 객체를 가르키는 주소를 가지고 있습니다.
 - 힙 영역에 저장됩니다.

 

이러한 참조형식의 데이터를 사용할 때 우리는 복사(copy)에서 종종 실수를 하고는 합니다.

아래와 같은 코드를 살펴봅니다.

import java.util.Arrays;
import java.util.List;

public class ArrayAndList {

    public static void main(String[] args) {
		
        String array[] = {"data1", "data2", "data3"};
        String copyArray[] = array;
		
        copyArray[1] = "바꾸기";
		
        System.out.println(Arrays.toString(copyArray));
        System.out.println(Arrays.toString(array));
    }
}

 

array라는 변수에 3개의 문자열을 대입하였고, copyArray라는 변수에는 array 변수를 대입 하였습니다.

그러면 여기서 하는 실수가 바로 그 다음줄에서 나오는 모습 입니다.

copyArray[1] = "바꾸기";

이러한 문제를 만나는 사람들은 아래와 같은 답변을 합니다.

 

"복사된 배열에 값을 넣었는데 기존 배열의 값이 바뀌었습니다."

 

바쁘다보면 가끔하는 실수..아닌가요..?ㅎ;;

 

자바에서의 참조형식의 데이터는 보관된 데이터의 주소값을 가지고 있습니다.

그러므로 위 코드에서도 배열값을 복사하려 한 다면 단순하게 대입연산자를 통하여 해주는 것이 아니라 반복문 또는 만들어진 클래스 등을 통하여 새로이 생성(new)하여 주어야 합니다.

 

위 코드를 간단하게 고쳐보면 아래처럼 clone 이라는 메소드를 통해 새로운 배열을 생성 해 낼 수 있습니다.

물론 1차원 이상의 배열(2차, 3차 등등)에서는 clone메소드가 원활하게 동작하지 않습니다. ^^;

import java.util.Arrays;
import java.util.List;

public class ArrayAndList {

    public static void main(String[] args) {
		
        String array[] = {"data1", "data2", "data3"};
        //String copyArray[] = array;
        String copyArray[] = array.clone();  //clone메소드를 사용 합니다.
		
        copyArray[1] = "바꾸기";
		
        System.out.println(Arrays.toString(copyArray));
        System.out.println(Arrays.toString(array));
    }
}

 

이를 실행하여 본 모습입니다.

예상한 바와 같이 각각의 변수가 서로 다른 곳의 데이터를 바라보기 때 문에 복사된 배열의 값이 바뀌더라도 기존 배열의 값은 영향을 받지 않습니다.

굿!

 

위 내용과 마찬가지로 컬렉션에서의 데이터도 비슷합니다.

1개의 변수를 생성한 뒤에 마찬가지로 간단하게 대입연산자를 통해 또다른 변수를 만들어 줍니다.

import java.util.Arrays;
import java.util.List;

public class ArrayAndList {

    public static void main(String[] args) {
		
        String array[] = {"data1", "data2", "data3"};
        //String copyArray[] = array;
        String copyArray[] = array.clone();  //clone메소드를 사용 합니다.
		
        copyArray[1] = "바꾸기";
		
        //System.out.println(Arrays.toString(copyArray));
        //System.out.println(Arrays.toString(array));
        
        //리스트를 한번 해 보면..
        List<String> list = Arrays.asList("list data1", "list data2", "list data3");
        List<String> copyList = list;
        
        copyList.set(1, "리스트 데이터 바꾸기");  //복사된 곳 데이터 바꾸기!
	
        System.out.println(list);
        System.out.println(copyList);	        
    }
}

 

list 변수의 내용을 간단하게 copyList 라는 변수에 대입하였습니다.

두개의 변수는 같은 공간의 데이터를 바라보기 때문에 어느 한쪽이 변화되면 다른 한쪽도 영향을 받습니다.

그러므로 위 코드도 list와 copyList의 데이터가 서로 변한 상태로 나타나게 됩니다.

이러한 형상을 방지하기 위해서는 새롭게(new) 만들어 주도록 코드를 수정해야 합니다.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ArrayAndList {

    public static void main(String[] args) {
		
        String array[] = {"data1", "data2", "data3"};
        //String copyArray[] = array;
        String copyArray[] = array.clone();  //clone메소드를 사용 합니다.
		
        copyArray[1] = "바꾸기";
		
        //System.out.println(Arrays.toString(copyArray));
        //System.out.println(Arrays.toString(array));
        
        //리스트를 한번 해 보면..
        List<String> list = Arrays.asList("list data1", "list data2", "list data3");
        //List<String> copyList = list;
        List<String> copyList = new ArrayList<>(list);  //new를 통한 새로운 할당
        
        copyList.set(1, "리스트 데이터 바꾸기");  
	
        System.out.println(list);
        System.out.println(copyList);	        
    }
}

 

ArrayList를 새로이 생성(new) 해 줌으로써 간단하게 해결 하였습니다.

 

자바(Java)에서의 참조형 데이터는 이처럼 서로 같은 공간을 바라보기 때 문에 항상 유의하여야 합니다.

대입 연산자로 내가 새로이 만들었다고 착각하는 순간 원래의 데이터가 바꾸어지기 때문 입니다.

 

이상으로 간단하게 살펴본 자바(Java)에서의 참조형 데이터에 관한 내용이였습니다.

궁금한점 또는 틀린 부분은 언제든 연락주세요!👻

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글