관리 메뉴

너와 나의 스토리

[Java 기초부터 다시] 4. 데이터 - 참조 타입/JVM/Enum 본문

Programming Language/Java

[Java 기초부터 다시] 4. 데이터 - 참조 타입/JVM/Enum

노는게제일좋아! 2021. 4. 7. 11:34
반응형

자바의 데이터 타입

  • Primitive type(원시 타입)
    • 정수, 실수, 문자열, 논리 리터럴을 저장하는 타입.
    • 실제 값을 변수 안에 저장.
  • Reference type(참조 타입)
    • 객체(Object)의 번지를 참조하는 타입. 
    • 배열, 열거, 클래스, 인터페이스 타입을 말한다.
    • 메모리의 번지를 값으로 변수에 저장.
  • 변수는 stack 영역에 생성되고, 객체는 heap 영역에 생성된다.
    • 참조 타입 변수는 heap 영역에 저장된 객체의 주소를 갖는 것.

 

메모리 사용 영역: JVM이 사용하는 메모리 영역

  • java.exe로 JVM이 시작되면 JVM은 운영체제에서 할당받은 메모리 영역(Runtime Data Area)을 사용한다.
  • 이 메모리 영역을 다음과 같이 세부 영역으로 구분해서 사용한다.
    • 메소드 영역(Method Area)
    • 힙 영역(Heap Area)
    • 스레드(Thread)-JVM Stack

 

메소드 영역

  • 코드에서 사용되는 클래스들을 클래스 로더로 읽어 클래스별로 Runtime Constant Pool, Field Data, Method Code, Constructor Code 등을 분류해서 저장한다.
  • 메소드 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역이다.

 

힙 영역

  • 객체와 배열이 생성되는 영역.
  • 힙 영역에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다. 
    • 해당 객체를 참조하는 변수나 필드가 없다면 필요 없는 객체이므로 JVM은 Grabage Collector를 실행시켜 이 객체를 제거한다.
    • * 자바는 코드로 객체를 직접 제거시키는 방법을 제공하지 않음

 

JVM Stack 영역

  • JVM 스택 영역은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다.
    • 디폴트로 main thread 존재(JVM 스택 하나)
  • JVM 스택은 메소드를 호출할 때마다 프레임(frame)을 추가(push)하고, 메소드가 종료되면 해당 프레임을 제거(pop)하는 동작을 수행한다. 
  • 예외 발생 시 사용하는 printStackTrace() 메소드에서 출력되는 내용의 각 라인은 하나의 프레임을 표현한다.
  • 프레임 내부에는 로컬 변수 스택이 있다.
    • 변수는 선언된 블록에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거된다.

 

참조 변수의 ==, != 연산

  • 기본 타입 변수의 ==, != 연산
    • 변수의 값이 같은지, 다른지 조사
  • 참조 타입 변수들 간의 ==, != 연산
    • 동일한 객체를 참조하는지, 다른 객체를 참조하는지 조사
    • 즉, 주소값을 비교

 

null과 NullPointerException

  • 참조 타입 변수를 null로 초기화할 수 있다.
    • null로 초기화된 변수는 스택 영역에 생성된다.
  • 참조 타입 변수가 null 값을 가지는지 확인하는 방법: ==, !=
    • refVar1 == null  -> true
  • null 값을 가지는 참조 타입 변수를 사용하면 NullPointerException이 발생한다.

 

 

배열 타입

  • 배열 선언: 아래의 두 가지 방식으로 선언할 수 있다.
    • 타입[] 변수;
    • 타입 변수[];
  • 값 목록으로 배열 생성
int[] scores = { 83, 90, 94};
  • 배열 변수를 이미 선언한 후에 다른 실행문에서 중괄호를 사용한 배열 생성은 허용되지 않는다.
  • 한 번 생성한 배열은 크기를 변경할 수 없다.
int[] scores;
scores = { 83, 90, 94}; // compile error
  • 하지만, new 연산자를 이용한 배열 생성은 가능하다.
int[] scores;
scores = new int[] { 83, 90, 94};
  • new 연산자로 배열 객체 생성
    • 타입[] 변수 = new 타입[길이];
int[] scores = new int[10];
int[0] = 0;
int[1] = 1;
// ...

 

 

객체를 참조하는 배열

String[] strArray = new String[3];
strArray[0] = "Java";
strArray[1] = "Java";
strArray[2] = new String("Java");


strArray[0] == strArray[1] // true -> 같은 객체를 참조
strArray[0] == strArray[2] // false -> 다른 객체를 참조
strArray[0].equals(strArray[2]) // true -> 문자열이 동일
  • 각 String 배열의 항목도 단일 String 변수들과 동일하게 작동한다.

 

배열 복사

  • 배열은 한 번 생성하면 크기를 변경할 수 없다.
  • 더 많은 저장 공간이 필요하다면, 큰 배열을 새로 만들어 이전 배열로부터 항목 값들을 복사해와야 한다.
  • System.arraycopy() 메소드를 사용하면 배열 간의 항목 값들을 복사할 수 있다.
    • System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
String[] oldStrArray = { "java", "array", "copy" };
String[] newStrArray = new String[5];

System.arraycopy( oldStrArray, 0, newStrArray, 0, oldStrArray.length);

// newStrArray -> { "java", "array", "copy", null, null }
  • for문으로 newStrArray 조회하기
for (String arr: newStrArray){
	// newStrArray의 크기는 5이지만
	// 값이 3개만 들어있으므로(나머지 null)
	// for문은 3번만 돌게 된다.
}

 

 

Enum 타입

public enum State {
    SUCCESS,
    FAIL,
    ABORT
}
  • 사용법: State state = State.SUCCESS;
    • null로 초기화도 가능
  • name() 메소드
    • enum 객체 내부의 문자열을 리턴한다.
State state = State.SUCCESS;

String stateStr = state.name(); // stateStr -> "SUCCESS"
  • ordinal() 메소드
    • 전체 enum 객체 중 몇 번째 enum 객체인지 알려준다.
State state = State.SUCCESS;

int ordinal = state.ordinal(); // ordinal -> 0
  • compareTo() 메소드
    • 주어진 enum 객체를 기준으로 전후로 몇 변째 위치하는지를 비교
State state1 = State.SUCCESS;
State state2 = State.FAIL;

int res1 = state1.compareTo(state2); // res1 -> -1
int res2 = state2.compareTo(state1); // res2 -> 1
  • values() 메소드
    • 모든 enum 객체들을 배열로 만들어 리턴한다.
State[] states = State.values();

 

 

 

 

출처:

- [이것이 자바다]

반응형
Comments