자바의 데이터 타입에는 크게 기본 타입과 참조 타입으로 분류된다.
기본 타입이란정수, 실수, 문자, 논리 리터럴
을 저장하는 타입을 말한다.
참조 타입이란 객체(Object)의 번지를 참조하는 타입으로배열, 열거, 클래스, 인터페이스
타입을 말한다
기본 타입으로 선언된 변수와 참조 타입으로 선언된 변수의 차이점은 저장되는 값이 무엇이냐
이다. 기본 타입인 byte, char, short, int, long, float, double, boolean을 이용해서 선언된 변수는 실제 값을 변수 안에 저장하지만, 참조 타입인 배열, 열거, 클래스, 인터페이스를 이용해서 선언된 변수는 메모리의 번지를 값
으로 갖는다. 번지를 통해 객체를 참조한다는 뜻에서 참조 타입이라고 부른다.
//기본 타입 변수
int age=30;
double price=100.5;
//참조 타입 변수
String name="김자바";
String hobby="독서";
int와 double 변수인 age와 price는 직접 값을 저장하고 있지만, String 클래스 변수인 name과 hobby는 힙 영역의 String 객체 주소 값을 가지고 있다. 주소를 통해 객체를 참조한다는 뜻에서 String 클래스 변수를 참조 타입 변수라고 한다.
메소드 영역에는 코드에서 사용되는 클래스(~.class)들을 클래스 로더로 읽어 클래스별로 런타임 상수풀(runtime constant pool), 필드(field) 데이터, 메소드(method) 데이터, 메소드 코드, 생성자(constructor) 코드 등을 분류해서 저장한다. 메소드 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역
이다.
힙 영역은 객체와 배열이 생성되는 영역
이다. 힙 영역에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다. 참조하는 변수나 필드가 없다면 의미 없는 객체가 되기 때문에 이것을 쓰레기로 취급하고 JVM은 쓰레기 수집기(Garbage Collector)를 실행시켜 쓰레기 객체를 힙 영역에서 자동으로 제거한다.
JVM 스택 영역은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다.
자바 프로그램에서 추가적으로 스레드를 생성하지 않았다면 main 스레드만 존재하므로 JVM 스택도 하나이다. JVM 스택은 메소드를 호출할 때마다 프레임(Frame)을 추가(push)하고 메소드가 종료되면 해당 프레임을 제거(pop)하는 동작을 수행한다. 예외 발생 시 printStackTrace() 메소드로 보여주는 Stack Trace의 각 라인은 하나의 프레임을 표현한다. 프레임 내부에는 로컬 변수 스택이 있는데, 기본 타입 변수와 참조 타입 변수가 추가(push)되거나 제거(pop)된다. 변수가 이 영역에 생성되는 시점은 초기화가 될 때, 즉 최초로 변수에 값이 저장될 때이다.
변수는 선언된 블록 안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거된다.
기본 타입 변수는 스택 영역에 직접 값을 가지고 있지만, 참조 타입 변수는 값이 아니라 힙 영역이나 메소드 영역의 객체 주소를 가진다. 자바에서는 배열을 객체로 취급한다
기본 타입 변수의 ==, != 연산은 변수의 값이 같은지, 아닌지를 조사하지만 참조 타입 변수들 간의 ==, != 연산은 동일한 객체를 참조하는지, 다른 객체를 참조하는지 알아볼 때 사용된다. 참조 타입 변수의 값은 힙 영역의 객체 주소이므로 결국 주소 값을 비교하는 것이 된다. 동일한 주소 값을 갖고 있다는 것은 동일한 객체를 참조한다는 의미이다.
따라서 동일한 객체를 참조하고 있을 경우 ==연산의 결과는 true이고 !=연산의 결과는 false이다.
위 그림에서 var1과 var2는 서로 다른 객체를 참조하고 있으므로 ==및 != 연산의 결과는 다음과 같다
var1==var2 //false
var1!=var2 //true
var2와 var3은 동일한 객체2를 참조하고 있으므로 ==및 != 연산의 결과는 다음과 같다
var2==var3 //true
var2!=var3 //false
참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 뜻
으로 null값을 가질 수 있다. null 값도 초기값으로 사용할 수 있기 때문에 null로 초기화된 참조 변수는 스택 영역에 생성된다.
참조 타입 변수가 null 값을 가지는지 확인하려면 다음과 같이 ==, != 연산을 수행하면 된다. var1은 힙 영역의 객체를 참조하므로 연산의 결과는 다음과 같다
var1==null //false
var1!=null //true
var2는 null 값을 가지므로 연산의 결과는 다음과 같다
var2==null //true
var2!=null //false
자바는 프로그램 실행 도중에 발생하는 오류를 예외(Exception)라고 부른다. 참조 변수를 사용하면서 가장 많이 발생하는 예외 중 하나로 NullPointerException이 있다. 이 예외는 참조 타입 변수를 잘못 사용하면 발생한다. 참조 타입 변수가 null을 가지고 있을 경우, 참조 타입 변수는 사용할 수 없다. 참조 타입 변수를 사용하는 것은 곧 객체를 사용하는 것을 의미하는데, 참조할 객체가 없으므로 사용할 수가 없는 것이다.