본문 바로가기
java

[Java] 레퍼런스타입

by jinbro 2017. 1. 16.




자바의 변수형은 프리미티브 타입과 레퍼런스 타입으로 나뉜다.


- 프리미티브타입 : short, int, long, char, boolean, float, double / 값을 변수에 대입하여 사용하는 형태

- 레퍼런스타 : 클래스, 인터페이스, 배열, 열거형 / 값을 변수에 대입하지만 변수는 참조값(메모리상)을 가지고있지 값(프리미티브타입 값들로 이루어진)을 직접 들고있지는 않는 것이 특징이다.



레퍼런스타입의 특징을 예시로 살펴보면 다음과 같다.



1) 왼쪽의 코드 결과는 오른쪽과 같다.

2) str1의 값이 참조값에 저장된다. 

3) str2의 변수에 str1의 참조값을 대입한다.

4) sysout을 통해 결과값을 보면 true로 나온다. 프리미티브타입에 비춰서 생각해보면 str1의 문자열을 str2에 대입했다고 생각하겠지만 그런 것이 아니라 str1이 참조하고 있는 값의 메모리값을 대입한 것이다. 그래서 str1이나 str2 둘 중 하나의 값을 변경하고 난 뒤에 str1 str2 둘 다 출력을 해도 하나의 문자열 값만 바뀐 것이 아니라 둘 다 문자열 값이 변경된 것을 볼 수 있다. 그리고 여전히 둘 다 == 을 통해 메모리 값을 비교하면 서로 같다고 true를 출력한다.

결론) 레퍼런스 타입은 값을 직접 들고 있는 것이 아니라 값을 참조할 수 있는 메모리상의 값을 들고 있는 것을 알 수 있다.

추가) String에서 == 은 메모리값을 비교하는 것이며, equals는 값 자체를 비교하는 것이다.




레퍼런스타입이 아무런 값을 참조하지 않도록 하는 값이 바로 null이다.

아무런 값을 참조하지 않는다는 것이 빈 값을 가지고 있다는 것이랑 같은 말이 아니다.

아래의 예시를 통해서 그 차이를 알아보았다.



1) p1은 객체만 생성하였고(객체에 대한 메모리는 가짐) 멤버변수에만 값을 넣지 않은 상태이다.

2) p2는 객체 생성을 하지 않고 변수에 null(아무런 값도 참조하지 않음)을 넣었다.

3) p1 객체의 멤버변수값들을 sysout으로 출력하였을 때 int 값이 아무런 값도 지정되지 않았을 때 나오는 0이 나왔지만(객체에 대한 메모리상의 주소값이 존재하기때문에), p2는 아무런 값도 참조하지 않는다라고 선언해두고 없는 멤버변수를 참조하였을 때에는 NullPointerException이 발생한다. 익셉션에 대한 처리는 호출하는 쪽에서 처리하거나 호출받는 쪽에서 처리를 하면된다. 또는 조건문을 가지고 null일 때를 처리하면된다.

결론) 아무런 값을 참조하지 않는다라고 변수에 대입해두고 값을 참조하기 위해서 변수를 출력하는 것은 익셉션으로 가는 지름길




댓글