//기본 타입 변수의 예
int age=28;
double price=100.5;
//참조 타입 변수의 예
String name="신용권";
String hobby="독서";
예시를 이용하여 메모리에서 변수들이 갖는 값을 표로 표현해보자.
// 메모리 : static, heap, stack 으로 이루어짐
1) 메모리 스택(stack)영역 :
기본 타입 변수 => 기본 타입 변수는 직접 값을 저장하고 있다.
변수명 | 변수값 |
---|---|
age | 28 |
price | 100.5 |
참조 타입 변수 => 힙 영역의 String 객체 번지 값을 가지고 있다.
변수명 | 메모리의 번지 |
---|---|
name | 100 |
hobby | 200 |
2) 메모리 힙(heap) 영역 :
참조 타입 변수 존재
메모리의 번지 | String 객체 |
---|---|
100번지 | 신용권 |
200번지 | 독서 |
JVM은 운영체제에서 할당받은 메모리 영역을 메소드 영역, 힙 영역, 스택 영역으로 구분해 사용한다.
비교 연산자(==, !=)가 기본 타입에서 사용되면 변수의 값이 같은지, 다른지 비교하지만, 참조타입에서 사용되면 동일한 객체를 참조하는지 아닌지 번지를 비교한다. ==가 true가 나오면 같은 객체를 참조하고 false가 나오면 다른 객체를 참조한다는 뜻이다.
// 동일한 번지값을 갖고 있으면 동일한 객체를 참조한다.
int[] intArray=null;
intArray[0]=10;
//intArray는 배열변수로, 참조변수라 null로 초기화 가능
//intArray 변수가 참조하는 배열 객체가 없기 때문에 10을 저장하려하면 NullPointerException 발생
String 변수를 선언하고 동시에 문자열을 저장할 수 있다.
String 변수 ="문자열";
2개의 String 변수를 선언하고 문자열을 저장할 수 있다.
String name;
name="신용권";
String hobby="자바";
문자열 리터럴이 동일하다면 String 객체를 공유할 수 있다.
String name1="신용권";
String name2="신용권";
//=> name1과 name2 변수가 동일한 문자열 리터럴인 "신용권"을 참조할 경우 name1과 name2는 동일한 String 객체를 참조하게 된다.
일반적으로 변수에 문자열 저장할 경우 문자열 리터럴 사용
new 연산자를 사용해 직접 String 객체를 생성시키는 것도 가능하다.
// new 연산자 : 객체 생성 연산자, 힙 영역에 새로운 객체를 만들 때 사용하는 연산자다.
String name3= new String("신용권")
String name4= new String("신용권")
//name3과 name4는 서로 다른 String 객체를 참조, 객체의 번지가 달라진다
참조를 잃은 String 객체는?
JVM이 참조되지 않은 객체를 쓰레기 객체로 취급하고 쓰레기 수집기(Garbage Collector)구동, 메모리에서 자동 삭제한다.
String name1="신용권";
String name2="신용권";
String name3= new String("신용권")
//String name1==String name2
//=> 결과 :true
//=> name1, name2 동일한 문자열 리터럴로 생성된 객체를 참조하기 때문
//String name1==String name3
//=> 결과 :false
//=> name3은 new 연산자로 String 객체를 별도로 생성했기 때문에 name1과 번지가 같지 않다.