티스토리 뷰

자바에서 데이터 타입은 크게 기본 타입(primitive type)과 참조 타입(reference type)으로 구분된다.

이번 포스팅에서는 이 참조 타입에 대해서 좀 더 자세히 다뤄보도록하자. 

 

🟩 데이터 타입의 분류

기본 타입으로 선언된 변수와 참조 타입으로 선언된 변수의 차이점은 저장되는 값이다.

기본 타입으로 선언된 변수는 값 자체를 저장하고 있지만,

참조 타입으로 선언된 변수는 객체가 생성된 메모리 *번지를 저장한다.

(

 *번지란?

데이터가 저장되어 있는 기억 장소의 위치

)

예를 들어보자.

// 기본 타입 변수
int age = 25;
double price 100.5;

// 참조 타입 변수
String name = "신용권";
String hobby = "독서";

이렇게 변수들을 선언했을 때, 메모리 상에서 이 변수들이 갖는 값을 그림으로 표현하면 아래와 같다.

 

 

또 변수들은 모두 스택(stack)이라는 메모리 영역에 생성된다. 

 

즉, 

기본 타입 변수인 age와 price는 직접 값을 저장하지만,

참조 타입 변수인 name과 hobby는 힙 메모리 영역의 String 객체 번지를 저장하고, 이 번지를 통해서 String객체를 참조한다. 

 

아주 간단하게 말하면,

기본 타입 변수는 직접 값을 스택에 저장하고,

참조 타입 변수는 직접 값을 저장하는 것이 아닌, 객체의 번지를 저장한다.

 

 

🟩 메모리 사용 영역 

이제는 메모리 사용 영역에 대해서 알아보자. 

java명령어로 JVM이 구동 되면 JVM은 운영체제에서 할당받은 메모리 영역(Runtime Data Area)을 다음과 같이 구분해서 사용한다. 

 

🔵 메소드 영역 

- 메소드(Method) 영역은 바이트 코드 파일(.class)을 읽은 내용이 저장되는 영역으로, 

클래스 별로 상수, 정적 필드, 메소드 코드, 생성자 코드 등이 저장된다. 

즉, 프로그램 실행에 필요한 클래스 정보를 저장하는 영역이다. 

간단히 말해서 바이트코드(.class) 파일의 내용이 저장되는 영역으로 알고 있자! 

 

🔵 힙 영역 

힙(Heap) 영역은 객체가 생성되는 영역이다. 

이 객체들의 번지는 메소드 영역의 상수와 스택 영역의 변수에서 참조할 수 있다

 

🔵 스택 영역 

스택(Stack)영역은 메소드를 호출할 때마다 생성되는 프레임(Frame)이 저장되는 영역이다. 

메모스 호출이 끝나면 프레임은 자동 제거된다. 

기본 타입 변수와 참조 타입 변수는 프레임 내부의 로컬 변수 스택이라는 곳에서 생성되고 제거된다. 

 

여기서 말하는 프레임에 대해서 좀 더 설명을 하자면,

프레임이란,

메서드가 일하는 동안 쓰는 임시 작업 상자라고 생각하면 될 것 같다.

메서드가 호출되면 상자가 하나 생기고,
끝나면 상자째로 버린다.

그래서 지역변수는 메서드가 끝나면 사라진다.

 

좀 더 정확히, 이 프레임 안에는 

  1. 지역 변수 저장 공간 (Local Variable Table)
  2. 연산 중 임시값을 저장하는 공간 (Operand Stack)
  3. 어디로 돌아가야 하는지 정보 (Return address)

이 있다. 

 

 

+)

추가적으로 메소드 영역과 힙 영역에 대해서 보충설명을 하겠다.

메소드 영역은 말그대로 프로그램 실행에 필요한 클래스 정보를 저장하는 영역이다.

예를 들자면,

  • 클래스의 이름
  • 부모 클래스 정보
  • 필드(멤버 변수) 목록
  • 메소드 목록과 바이트코드
  • static 변수
  • 런타임 상수 풀(runtime constant pool)

와 같은 정보들. 

 

다음으로 힙 영역은 new 연산자를 통해 생성된 실제 객체(instance) 가 저장되는 공간이다.

예시를 들어보자.

new Person();
new Person();
new Person();

 

이렇게 객체를 3개 생성했다고 하자.

이렇게 되면,

힙 영역에는 3개의 Person 객체가 저장되지만,

메소드 영역의 Person 클래스 정보는 딱 하나이다.

 

🟣 Garbage Collector

어떤 변수에서도 특정 객체를 참조하지 않으면, 해당 객체는 프로그램에서 사용할 수 없는 객체가 된다.

즉, 힙 메모리에는 있지만, 위치 정보를 모르기 때문에 사용할 수 없다.

자바는 Garbage Collector를 실행시켜서 이러한 객체를 자동으로 제거한다.

 

🟩 문자열 (String) 타입

자바의 문자열은 String 객체로 생성된다.

 

그리고,

자바는 문자열 리터럴이 동일하다면 String 객체를 공유하도록 설계되어 있다.

즉,

String name1 = "홍길동";
String name2 = "홍길동";

이렇게 name1과 name2 변수에 "홍길동"을 대입했을 경우, name1과 name2 변수에는 동일한 String 객체의 번지가 저장된다.

 

일반적으로는 위와 같이 String 변수에 문자열 리터럴을 대입하는 것이 일반적이지만, new 연산자로 직접 String객체를 생성하고 대입할 수도 있다.

String name1 = new String("홍길동");
String name2 = new String("홍길동");

 

이 경우, name1과 name2는 서로 다른 String 객체의 번지를 가지게 된다.

 

 

 

이제 문자열 비교를 해보자. 

( 참고로 참조 타입 변수의 ==!= 연산자는 피연산자의 번지를 비교하는 것이다!)

String name1 = "홍길동";
String name2 = "홍길동";
String name3 = new String("홍길동");

System.out.println(name1 == name2); // true
System.out.println(name1 == name3); // false
System.out.println(name2 == name3); // false

 

 

그리고 String 객체에 이용할 수 있는 몇가지 메서드가 있지만, 아주 간단하게만 적겠다.

charAt() - 문자열에서 특정 위치의 문자 얻기

lentth() - 문자열의 길이

replace() - 문자열에서 특정 문자열 다른 문자열로 대체하기

substring() - 특정 위치의 문자열을 잘라내기

indexOf() - 특정 문자열의 위치 찾기

split() - 문자열 분리하여 배열로 다루기 

......

 

 

🟩 배열(Array) 타입 

이 블로그에서 굳이 배열 타입이 뭔지, 어떻게 선언하는지 등은 정리하지 않겠다. ( 책에서 몰랐던 내용만!)

 

🔵 타입에 따른 배열 기본값

new 연산자로 배열을 처음 생성하면, 배열 항목은 기본값으로 초기화된다.

간단하게 말하자면,

정수 배열은 0 으로 초기화, 
실수 배열은 0.0 으로 초기화, 
논리 배열은 false로 초기화, 
참조 배열은 null로 초기화 
된다. 

 

 

🟩 main()메소드의 String[] 매개변수 용도

class HelloWorld {
    public static void main(String[] args) {
        
    }
}

 

자바에서 프로그램을 실행하기 위해서는 항상 이렇게 문자열 배열 형태의 String[] args 매개변수를 가진 main메서드를 작성했었는데, 

여기서 이 매개변수가 왜 필요한지 알아보자.

 

윈도우의 명령 프롬프트나 맥OS의 터미널에서 프로그램을 실행할 때는 요구하는 값이 있을 수 있다.

예를 들어서, 두 수를 입력받고 덧셈을 수행하는 프로그램은 실행할 때 앞서 말한 두 수를 요구할 수 있다.

즉, 이렇게 프로그램을 실행 할때, 사전에 요구되는 값을 매개값으로 전달시켜야하는 상황에 String[] args라는 main메서드의 매개변수가 사용된다

 

이 설정은 인텔리제이에서 설정할 수 있다. 

아래 Configuration 항목에 들어가서, Program arguments를 설정해주면 된다.

( 그리고 공백기준으로 배열 항목 값을 구성하는 것 같다. )

 

 

 

나는 Program arguments에 "hi hello"를 넣어주었다.

아래는 그 예시 코드이다.

class HelloWorld {
    public static void main(String[] args) {
        System.out.println(args.length); // 2
        System.out.println(args[0]); // hi
        System.out.println(args[1]); // hello
    }
}

 

 

여기까지...

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함