주소를 가리키는 Reference 참조 타입
java에서 참조 타입에 대해 알아봅니다.
목 차
🧩1. 데이터 타입 분류
🧩2. 메모리 사용 영역
🧩3. 참조 변수의 ==, !=연산
🧩4. Null과 NullPointException
🧩5. String 타입
🧩6. 배열 타입
🧩7. 열거 타입
🧩1. 데이터 타입 분류
변수의 메모리 사용
- 기본 타입 변수 👉 실제 값을 변수 안에 저장
- 참조 타입 변수 👉 주소를 통해 객체 참조
#기본 타입 변수 -> 스택(stack) 영역에 저장
int age = 25;
double price = 100.5;
#참조 타입 변수 -> 힙(heap) 영역에 저장
String name = "홍길동";
String hobby = "독서";
🧩2. 메모리 사용 영역
JVM이 사용하는 메모리 영역
- 메소드 영역
- JVM 시작할 때 생성
- 로딩된 클래스 바이트 코드 내용을 분석 후 저장
- 모든 스레드가 공유
- 힙 영역
- JVM 시작할 때 생성
- 객체/배열 저장
- 사용되지 않는 객체는 Garbage Collector가 자동 제거
- JVM 스택
- 스레드 별 생성
- 메소드 호출할 때마다 Frame을 스택에 추가(push)
- 메소드 종료되면 Frame 제거(pop)
🧩3. 참조 변수의 ==, !=연산
변수의 값이 같은지 다른지 비교
- 기본 타입 : byte, char, short, int, long, float, double, boolean
- 변수의 값이 같은지 다른지 조사
- 참조타입 : 배열, 열거, 클래스, 인터페이스
- 동일한 객체를 참조하는지 다른 객체를 참조하는지 조사
🧩4. Null과 NullPointException
null(널)
- 참조 타입의 기본 값은 null 입니다.
- 변수가 참조하는 객체가 없을 경우 초기값으로 사용 가능합니다.
- 참조 타입의 변수에만 저장 가능합니다.
- null로 초기화된 참조 변수는 스택 영역 생성합니다.
- ==, != 연산이 가능합니다.
- null로 초기화된 경우 refVal == null 의 결과는 true 입니다.
- 초기화 전에 refVal == null의 결과는 false 입니다.
🧩5. String 타입
문자열을 저장하는 클래스 타입
- 변수가 선언되면 stack에 '주소'가 저장되며, '홍길동' 실제 데이터는 heap에 저장됩니다.
String name;
name = "홍길동"
- 문자열 리터럴 동일하다면 String 객체 공유합니다. 즉, 같은 데이터를 다른 이름의 변수에 저장할 수 있습니다..
- new 연산자를 사용하여 String 객체를 생성하면, 힙 영역에 새로은 String 객체가 생성됩니다.
🧩6. 배열 타입
연속된 공간에 저장하는 자료구조
- 같은 타입의 데이터를 연속된 공간에 저장하는 자료구조입니다.
- 각 데이터 저장 위치는 인덱스를 부여해 접근합니다.
int score1=81;
int socre2=82: <score 배열>
. --------------------------
. |81|82| |75|
. --------------------------
int score30=75; <인덱스> 0 1 29
배열이름[인덱스]로 접근 ex) score[0]
배열 선언
- 배열을 사용하기 위해 우선 배열 변수를 선언합니다.
#타입[] 변수;
int[] intArray;
double[] doubleArray;
String[] strArray;
#타입 변수[];
int intArray[];
double doubleArray[];
String strArray[];
- 배열 변수는 참조 변수이므로, 배열이 생성되기 전 null로 초기화할 수 있습니다.
#배열 초기화 방법들
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] intArray1 = new int[] { 10, 20, 30, 40, 50 }; // 배열초기화 1
int[] intArray2 = { 10, 20, 30, 40, 50 }; // 배열초기화 2
int[] array3;
array3 = new int[] { 10, 20, 30, 40, 50 }; // 배열초기화 3
for (int i = 0; i < intArray1.length; i++) {
System.out.println(intArray1[i]);
}
}
}
- 다음과 같이 배열의 길이를 선언할 수도 있습니다.
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] intArray = new int[5];
intArray[0] = 10;
intArray[1] = 20;
intArray[2] = 30;
intArray[3] = 40;
intArray[4] = 50;
for (int i=0; i<intArray.length; i++) {
System.out.println(intArray[i]);
}
}
}
배열 길이
- 배열의 길이를 확인할 수 있습니다.
#타입[] 변수;
int[] intArray;
double[] doubleArray;
String[] strArray;
#타입 변수[];
int intArray[];
double doubleArray[];
String strArray[];
- 배열 변수는 참조 변수이므로, 배열이 생성되기 전 null로 초기화할 수 있습니다.
#배열 초기화 방법들
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] intArray1 = new int[] { 10, 20, 30, 40, 50 }; // 배열초기화 1
int[] intArray2 = { 10, 20, 30, 40, 50 }; // 배열초기화 2
int[] array3;
array3 = new int[] { 10, 20, 30, 40, 50 }; // 배열초기화 3
for (int i = 0; i < intArray1.length; i++) {
System.out.println(intArray1[i]);
}
}
}
- 다음과 같이 배열의 길이를 선언할 수도 있습니다.
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] intArray = new int[5];
intArray[0] = 10;
intArray[1] = 20;
intArray[2] = 30;
intArray[3] = 40;
intArray[4] = 50;
for (int i=0; i<intArray.length; i++) {
System.out.println(intArray[i]);
}
}
}
- 배열의 길이는 .length 로 확인 가능합니다.
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] intArray1= new int[] {10,20,30};
System.out.println(intArray1.length);
}
}
배열 복사
- 배열의 복사는 가벼운 복사(swallow cpoy)와 복제(deep copy)가 있습니다
- 가벼운 복사는 주소만 복사 되며, 복제는 실제 값을 복사합니다.
- 배열은 한번 생성하면 크기 변경이 불가능합니다.
- 더 많은 저장공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로 부터 항목 값(주소)들을 복사해야합니다.
- 배열 복사 방법은 다음과 같습니다.
- System.arrayCopy() 메소드 이용
- for 문 이용
- Arrays 클래스 이용
- 배열을 단순히 대입하게 되면, 하나의 실제 배열을 가리키는 주소만 복사가 됩니다.
- array 배열의 값이 변하면 대입된 배열 copy_array 의 값도 변합니다.
- 다음은 swallow copy의 예입니다.
#배열을 단순히 대입하게 되면, 하나의 실제 배열을 가리키는 주소만 복사가 된다.
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = new int[] { 10, 20, 30, 40, 50 };
int[] copy_array;
copy_array = array;
System.out.println(copy_array.length);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ", ");
}
System.out.println();
for (int i = 0; i < copy_array.length; i++) {
System.out.print(copy_array[i] + ", ");
}
}
}
- Deep copy 복제, System.arraycopy(src, srcPos, dest, destPos, length);
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = new int[] { 10, 20, 30, 40, 50 };
int[] copy_array = new int[10];
System.arraycopy(array, 0, copy_array, 0, array.length);
array[0] = 100;
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ", ");
}
System.out.println();
for (int i = 0; i < copy_array.length; i++) {
System.out.print(copy_array[i] + ", ");
}
}
}
- Deep copy 복제, for 문을 통해 배열 값을 하나 하나 대입
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = new int[] { 10, 20, 30, 40, 50 };
int[] copy_array = new int[10];
for (int i = 0; i < array.length; i++) {
copy_array[i] = array[i];
}
System.out.println();
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ", ");
}
System.out.println();
for (int i = 0; i < copy_array.length; i++) {
System.out.print(copy_array[i] + ", ");
}
}
}
- 향상된 for 문 for (int 변수 : 배열) { } 을 이용해서 복제할 수도 있습니다.
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = { 10, 20, 30, 40, 50 };
int[] copy_array = new int[10];
int i = 0;
for (int n : array) { // 향상된 for 문
copy_array[i] = n;
System.out.println(i);
System.out.println(copy_array[i]);
i++;
}
}
}
다차원 배열
- 2차원 이상의 배열을 구성할 수 있습니다.
- 2차원 배열이 많이 사용되며, 수학의 행렬과 같은 자료 구조입니다.
- x, y 좌표로 표현되는 표형태입니다.
- 자바는 1차원 배열을 이용하여 2차원 배열을 구현합니다.
- ⭐️ darray.length 는 줄의 갯수 를 나타냅니다.
- ⭐️ darray[0].length 는 0번째 줄의 배열 갯수를 의미합니다.
public class referType1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] darray = new int[2][3];
darray[0][1] = 1;
darray[0][1] = 1;
System.out.println(darray.length);
System.out.println(darray[0].length);
System.out.println(darray[1].length);
int[][] varray = new int[2][];
varray[0] = new int[3];
varray[1] = new int[4];
System.out.println(varray.length);
System.out.println(varray[0].length);
System.out.println(varray[1].length);
}
}
🧩7. 열거 타입
한정된 값만을 갖는 데이터 타입
- public enum Week { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY }
- public enum Week { LOGIN_SUCCESS, LOGIN_FAILED }
enum Color {RED,BLACK,WHITE,PURPLE,GREEN,YELLOW,GRAY}
public class EnumTest {
public static void main(String[] args) {
Color color=Color.RED;
}
}
- Calendar를 이용해 오늘의 요일을 얻고 열거 타입 변수에 해당 열거 상수를 대입하는 예제입니다.
import java.util.Calendar;
public class EnumWeekExample {
public static void main(String[] args) {
Week today = null;
Calendar cal = Calendar.getInstance();
int week = cal.get(Calendar.DAY_OF_WEEK);
switch(week) {
case 1:
today = Week.SUNDAY; break;
case 2:
today = Week.MONDAY; break;
case 3:
today = Week.TUESDAY; break;
case 4:
today = Week.WEDNESDAY; break;
case 5:
today = Week.THURSDAY; break;
case 6:
today = Week.FRIDAY; break;
case 7:
today = Week.SATURDAY; break;
}
System.out.println("오늘 요일: "+ today);
if(today == Week.SUNDAY) {
System.out.println("일요일에는 축구를 합니다.");
} else {
System.out.println("열심히 자바 공부합니다.");
}
}
}
0 댓글