[이것이 자바다] 5장 참조 타입
참조 타입(reference type)
객체(Object)의 번지를 참조하는 타입으로 배열, 열거, 클래스, 인터페이스 타입을 말한다.
배열, 열거, 클래스, 인터페이스를 이용해서 선언된 변수는 메모리 번지를 값으로 갖는다.
→ 번지를 통해서 객체를 참조한다는 의미

그림을 통해 메모리 저장 공간을 생각해보면 간단하게 변수는 스택 영역에 생성되며 객체는 힙 영역에 생성된다.
* 메모리 사용 영역
> 힙 영역
객체와 배열이 생성되는 영역이다.
힙에서 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체이 필드에서 참조된다.
참조하는 변수나 필드가 없다면 의미 없는 객체가 되기 떄문에 이것을 쓰레기로 취급하고 GC(가비지 컬렉션)를 실행시켜 쓰레기 객체를 힙 영역에서 자동으로 제거한다.
자바에서는 자동으로 메모리를 관리해주기 때문에 개발자는 객체를 제거하기 위해 별도 코드 작성이 필요 없다.
> 스택(stack) 영역
각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다.
추가 스레드를 생성하지 않을 경우 main 스레드만 존재하므로 JVM 스택도 하나이다.
스택은 메소드를 호출할 때마다 프레임을 추가하고 메소드가 종료되면 해당 프레임을 제거하는 동작을 수행한다.
기본 타입 변수는 스택 영역에 직접 값을 가지고 있지만 참조 타입 변수는 값이 아니라 힙 영역이나 메소드 영역의 객체 주소를 가진다.
참조 타입 변수들 간의 == , != 연산은 동일한 객체를 참조하는지, 다른 객체를 참조하는지 알아볼 때 사용된다.
값이 같은지 아닌지를 조사하는 것이 아니다!
* null과 nullPinterException
> null
참조 타입 변수에서는 힙 영역의 객체를 참조하지 않는다는 것을 뜻한다.
null 값으로도 초기값을 가질 수 있기 때문에 null로 초기화된 참조 변수는 스택 영역에 생성된다.
→ 힙 영역의 객체를 참조하지 않는다는 것을 의미하기 때문이다.
> nullPointterException
참조 타입 변수를 잘못 사용하면 발생하는 예외이다.
* String
String은 문자열을 저장하는 것이 아닌 문자열은 String 객체로 생성되고 변수는 String 객체를 참조하는 것이다.
자바에서는 문자열 리터럴이 동일하다면 String 객체를 공유하도록 되어 있다.
new 연산자를 사용해서 직접 String 객체를 생성시킬 수 있다.(new : 객체 생성 연산자)
String 초기값을 null로 대입하 경우 참조하는 객체가 없다는 것을 의미한다.
String 변가 값을 가지고 있다가 null을 대입하게 될 경우 더이상 객체를 참조하지 않도록 할 수 있으며 이렇게 참조를 잃은 String 객체는 JVM이 참조를 잃을 쓰레기 객체를 Garbage Collector를 이용하여 메모리에서 자동 제거한다.
* 배열
배열은 같은 타입의 데이터만 저장할 수 있으며, 선언과 동시에 저장할 수 있는 데이터 타입을 선언한다.
배열은 한 번 생성된 배열은 길이를 늘리거나 줄일 수 없다.
배열 선언 방법
타입[] 변수;
타입 변수[];
# 값 목록으로 배열 생성 방법
데이터타입[] 변수 = {값0, 값1, 값2, 값3 .......}
# new 연산자로 배열 생성
타입[] 변수 = new 타입[길이];
배열 길이 and 배열 복사
# 배열 길이
배열변수.length;
length 필드는 읽기 전용 필드이기 떄문에 값을 바꿀 수 없다.
배열인덱스는 0부터 시작한다.
# 배열 복사
for문 또는 System.arraycopy() 방법 이용
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
src : 원본 배열
srcPos : 원본 배열에서 복사할 항목의 시작 인덱스
dest : 새로운 배열
destPos : 새 배열에서 붙여넣을 시작 인덱스
length : 복사할 개수
# 배열 복사 사용 예시
public class ArrCopy{ public static void main(String[] args){ int[] oldArr = {1,2,3}; int[] newArr = new int[5]; System.arraycopy(oldArr, 0,newArr,0,oldArr.length); } }oldArr 배열이 newArr 배열로 복사가 된다.
oldArr 배열 인덱스 0번복사를 시작해 newArr 배열 0번 인덱스에 붙여넣기를 oldArr배열 길이만큼 복사할 것이다.
newArr 배열 크기는 5이고 oldArr 배열은 3이면 2개가 비워져 있다.
이렇게 비워져 있는 경우 null값으로 배열이 채워진다.
다차원 배열
예시
int[][] scores = new int[2][3];
가로 : 행 // 세로 : 열
0,0 0,1 0,2 1,0 1,1 1,2
# 다른 방법
타입[][] 변수 = {{값1,값2}, {값1,값2}}
그룹0 값 그룹1 값
열거 타입
데이터 중에는 몇가지로 한정된 값만을 갖는 경우가 있다.
한정된 값만을 갖는 데이터 타입이 열거 타입(enumeration type)이며 몇 개의 열거 상수(enumeration constant) 중에서 하나의 상수를 저장하는 데이터 타입이다.
열거타입 선언 방법
public enum Week{
MONDAY,
TUESDAY,
WENDESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
public enum 열거타입 이름 {....}로 선언한다.
열거 상수 같은 경우는 열거 타입의 값으로 사용되며, 관례적으로 모두 대문자로 작성한다.
열거 타입 변수
열거 타입도 하나의 데이터 타입이므로 변수를 선언하고 사용해야 한다.
열거타입 변수;
#예시
Week today;
Week reservationDay;
# 열거 타입 변수를 선언했다면 열거 상수를 저장할 수 있다. 열거 상수는 단독으로 사용할 수 없기 때문에 반드시 열거타입.열거상수로 사용된다.
열거타입 변수 = 열거타입.열거상수;
Week today = Week.SUNDAY;
열거 타입은 참조 타입이기 떄문에 null 적용이 가능하다.
# 열거 객체 메소드
리턴 타입 메소드(매개변수) 설명 String name() 열거 객체의 문자열을 리턴 int ordinal() 열거 객체의 순번(0부터 시작)을 리턴 int compareTo() 열거 객체를 비교해서 순번 차이를 리턴 열거 타입 valueOf(String name) 주어진 문자열의 열거 객체를 리턴 열거 배열 values() 모든 열거 객체들을 배열로 리턴