오늘은 참조타입에 대해서 학습했다. 학교 수업을 들을 땐, 메모리 효율, 메모리 영역 등 눈에 보이지 않는 부분들은 중요하게 생각하지 않고 눈에 보이는 부분들을 공부하는데 더 집중했지만 회사를 다니면서 이런 부분들도 중요함을 알게 되었기에 예전과는 다르게 느껴졌다.
위 그림을 보고 'String은 왜 없지?'라고 생각했는데 Java에서 String은 Class라는 사실을 잊고 있었다.
아무튼 기본 타입과 참조 타입의 가장 큰 차이점은 해당 타입의 변수를 생성했을 때, '변수에 어떤 값이 저장되는가'이다.
기본 타입
기본 타입 변수를 선언하고 초기화까지 했을 때, 스택(Stack)영역에 선언한 변수가 생기고 초기화했던 값이 담긴다.
참조 타입
참조 타입 변수를 선언하고 초기화까지 했을 때, 스택(Stack)영역에 선언한 변수가 생기고 초기화했던 값은 힙(Heap)영역에 객체로 생긴다. 이후, 스택 영역에 생성된 변수에 힙 영역에 생성된 객체의 주소 정보가 담긴다.
참조 타입은 처음 접했을 때, 이해하기 쉽지 않기에 조금 더 살펴보자.
1.1 기본 타입 변수
public static void main(String args[]){
int number = 100;
...
}
기본 타입 변수인 int형 변수를 선언하고 초기화까지 했을 때, 스택(Stack)에 'number'변수가 생기고 '100'이라는 값이 담긴다.
1.2 참조 타입 변수
public static void main(String args[]){
String name = "침착맨";
...
}
참조 타입 변수인 String형 변수를 선언하고 초기화까지 했을 때, 스택(Stack) 영역에 'name'변수가 생기고 힙 영역(Heap)에 초기화했던 값을 가진 String 객체가 생성된다. 스택 영역의 name은 생성된 객체의 주소를 참조한다.
참조 타입 변수는 선언하고 null로 초기화한다면 위 그림처럼 스택 영역에 null상태로 생성된다.
String을 사용할 때 조심해야 되는 부분은 비교이다.
익숙하고 제대로 알고 있다면 상관없지만 오랜만에 자바를 사용하거나 처음 사용한다면 String비교를 제대로 못하는 경우가 있다. 물론 나도 그랬다.
public static void main(String args[]){
String name1 = '손오공';
String name2 = '손흥민';
// #1
if(name1.equal(name2)){
System.out.print("동일");
}
// #2
if(name1 == name2){ // 동일한 객체를 참조하는지 확인하는 것
... // 참조하고 있는 값을 비교하는 것이 아니다.
}
}
String은 equal을 통해 스택(Stack)영역이 참조하는 객체의 값을 비교해야 한다.
'=='을 통해 비교한다면 두 개의 변수가 동일한 객체를 참조하는지 확인하는 것이기 때문에 올바른 값 비교를 할 수 없다.