IT/Java

[4] JAVA 참조 타입 , 메모리 사용 영역 총 정리

Lyk 2021. 1. 17. 21:15
728x90
반응형

JAVA 데이터 타입

1. 기본 타입과 참조 타입의 차이

기본 타입 : 정수, 실수, 문자, 논리 리터럴을 저장하는 타입

참조 타입 : 객체(Object)의 번지를 참조하는 타입

 

▶쉽게 말하면 기본 타입은 실제 값을 변수에 저장하고, 참조 타입은 메모리의 번지 값을 얻는다.

 

기본 타입(int)와 참조타입(Integer)의 차이

 


2. 메모리 사용 영역

메모리 사용 영역

메소드 영역 : 로딩된 클래스 바이트 코드 내용을 분석해 저장. JVM이 시작될 때 모든 스레드가 공유하는 영역

 

힙 영역 : 객체와 배열이 생성되는 영역. JVM이 시작될 때 생성. 참조하는 변수나 필드가 없다면 JVM이 쓰레기 수집기(가비지 컬랙터, Garbage Collector)를 실행시켜 쓰레기 객체를 힙 영역에 자동으로 제거

 

JVM 스택 영역 : 각 스레드마다 하나씩 존재. 메소드를 호출할 때마다 프레임을 추가(push), 메소드가 종료되면 해당 프레임을 제거(pop)하는 동작 수행. 참고로 스레드는 여러개 생성할 수 있고, 추가적으로 생성한 스레드가 없다면 main 초기엔 메인 스레드만 존재한다. 즉 초기 JVM 스택도 하나이다.


3. 참조 타입


1. String ( 대표적 참조 타입)

2. 배열 타입

같은 타입의 데이터를 연속된 공간에 저장하는 자료구조

각 데이터 저장 위치는 인덱스를 부여해서 접근할 수 있다.

 

① 선언

타입[] 변수;

or

타입 변수[];

 

아래 예시

int[] intArr;
String stringArr[];

② 배열 생성

배열 생성 타이밍은

바로 초기화 하거나 변수 생성 후 나중에 초기화할 수도 있다.

다만 중괄호로 간편하게 적는 방식은 변수 생성과 동시에만 사용 가능하다.

int[] arr = {1, 2, 3};
/* 이렇게는 불가능
* int[] arr;
* arr = {1, 2, 3};
* 변수를 선언하며 바로 값을 넣을 땐 new 연산자 없이 중괄호로 대입할 수 있지만 선언 후 값을 넣을 땐 그렇지 않다.
*/
int[] arr = new int[]{1, 2, 3};
int[] arr = new int[3];

 

3. 열거 타입

열거타입(enumeration type) : 한정된 값만 가지는 데이터 타입

 

선언

열거 타입 이름으로 소스 파일(.java)을 생성해야 한다.

열거 타입 이름은 파스칼 형식!

 

파스칼 형식이란?

 

예를 들어 요일에 대한 데이터를 저장하는 열거 타입을 선언한다면

예) 열거 타입 이름은 Week, 아래는 열거 상수들.

public enum 이라는 키워드를 이용해야 한다.

public enum Week {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}

사용할 땐 [열거 타입 이름].[열거 상수] 형식으로 사용할 수 있다.

System.out.println(Week.SUNDAY);	// SUNDAY

열거 객체 관련 메서드

Week we = Week.SUNDAY;
System.out.println("we : " + we); // we : SUNDAY

System.out.println(we.name());	// SUNDAY	// 열거 객체의 문자열 리턴
System.out.println(we.ordinal()); // 6, 열거 객체 순번(0부터)
System.out.println(we.compareTo(Week.MONDAY)); // 6 (열거객체 비교해서 순번 차이 리턴)
System.out.println(we.valueOf("SUNDAY"));	// SUNDAY(해당 문자열 열거 객체 리턴)
System.out.println(we.values());	// 모든 열거 객체 배열로 반환


4. 주의할 점

- NullPointException

객체 안에 null이 들어간 상태로 객체의 메서드를 실행하거나

이를 매게변수로 사용하여 어떤 함수를 실행할 때

NullPointException이 발생하기도 한다.

이런 오류가 발생했을 때엔 값이 잘 받아졌는지,

초기화가 제대로 이루어졌는지 확인해야 한다.

아마 자바를 공부하면 가장 많이 만나는 오류일 것이다.

- 같은 데이터를 저장할 때 같은 주소 참조

예로는 아래 코드처럼 먼저 "start"라는 변수를 참조하는 참조변수를 생성하고

아래에 같은 값을 참조하는 변수를 만들었을 때,

String st1 = "start";
String st2 = "start";

이렇게 같은 변수를 참조하게 된다.

 

만약 아래처럼 변수를 만들게 되면

		String st1 = "start";
		String st2 = "start";
		String st3 = new String ("start");
		
		System.out.println("st1 == st2 ? " + (st1 == st2)); // true
		System.out.println("st1 == st3 ? " + (st1 == st3)); // false
		System.out.println("st2 == st3 ? " + (st2 == st3)); // false

new 연산자를 이용해 힙 영역에 새로운 객체를 만들 수 있는데,

 

이렇게 만들어진 경우 단순 == 기호를 통해 비교하게 되면

start라는 글자가 아닌 주소값을 비교해 false를 반환하게 된다.

그래서 참조타입 변수는 제대로 비교하려면 equals를 사용해야 한다.

		String st1 = "start";
		String st2 = "start";
		String st3 = new String ("start");
		
		System.out.println("st1.equals(st2) : " + st1.equals(st2)); // true
		System.out.println("st1.equals(st3) : " + st1.equals(st3)); // true
		System.out.println("st2.equals(st3) : " + st2.equals(st3)); // true
728x90
반응형