ArrayList<Class> array = new ArrayList<Class>(); 형태의 ArrayList 가 있다고 할때, for문으로 객체를 넣을 때의 주의사항.



Mysql 에서 회원정보를 가져와 리스트를 만드는 과정에서 겪은 시행착오를 적습니다.

의도는 같은 분류에 속한 사람들을 가져와 ArrayList 에 추가해준 뒤 for문으로 뿌려주는 거 였습니다.




아래와 같이 Sample 이라는 클래스가 있고 이안에 num 이라는 변수가 있다고 하자.

Class Sample{

int num;

게터;    (모두 치기 귀찮아 생략합니다. getter 메소드)

세터;    (모두 치기 귀찮아 생략합니다. setter 메소드)

}


이 Sample 클래스의 객체를 for문을 통해 ArrayList에 아래와 같이 넣어보자.


Sample sample = new Sample();


ArrayList<Sample> array = new ArrayList<Sample>();


for(int i = 0 ; i < array.size() ; i++){

sample.setNum(i);

array.add(sample);

}


for(int i = 0 ; i < array.size() ; i++){

System.out.println(array.get(i).getNum());

}


위와 같은 형태로 for문으로 sample 객체에 i 값을 넣어주고 그를 array에 추가해주었을때,
내가 원하는 출력값은 0, 1, 2, 3, 4, 5, ... 와 같이 각기 다른 값이었다.

하지만 이렇게 나오지 않고, 이 경우에는 마지막 숫자가 똑같이 출력된다.
만약 array의 크기가 10이라면 9, 9, 9, ... 9 이렇게 9가 10번 출력된다.
이는 마지막에 sample 객체의 num 값을 9로 set 해주었기 때문이며,
Array에 추가된 sample객체는 모두 하나의 객체이기 때문이다.


추가적으로 설명하자면, 변수에는 기본형 변수와 참조형변수가 있다.
기본형 변수는 우리가 흔히 아는 char, int, long, double 과 같은 변수들이다.
이 변수들은 스택에 값을 직접 저장한다.

이와 다르게 참조형 변수는 직접 값을 저장하지 않는다.
대표적인 예로는 배열이나 String, 클래스 객체 등이 있다.
참조형 변수는 스택에 본래 값들이 있는 힙의 주소값이 들어가 있다. 즉, 값을 직접 저장하지 않는다.

위의 경우에는 sample은 모두 하나의 힙의 주소값을 갖고 있는 하나의 객체이다.
ArrayList에 넣었다 하더라도 들어간 객체들은 모두 하나의 주소값을 가지고 하나의 힙을 참조한다.
그렇기에 매번 setter로 num 값을 넣어 줄때마다 매번 sample 객체의 num값은 바뀐 것이며, 최종적으로 마지막 값이 들어가 모두 같은 값이 출력된 것이다. 



이럴 때, 0, 1, 2, 3, 4, 5, ... 와 같은 값을 얻으려면, 내가 한 방법은 이렇다

ArrayList<Sample> array = new ArrayList<Sample>();


for(int i = 0 ; i < array.size() ; i++){

Sample sample = new Sample();

sample.setNum(i);

array.add(sample);

}


for 문안에서 객체를 생성해주었다.
이렇게 했을 때는 원하는 결과를 얻을 수 있었다.
이것이 맞는 방법인지는 모르겠으나, 일단은 이렇게 해결했다.


어떻게 보면 너무나 당연한 굉장히 초보적인 실수를 한 것 같아 ashamed 하다




+ Recent posts