Java
값 형식과 참조형식
1space
2025. 7. 18. 19:56
값 형식(Value Type)과 참조 형식(Reference Type)이란?
값 형식 (Value Type)
int x = 7;
- 변수 x는 값 그 자체(7) 를 직접 저장합니다.
- 메모리 공간 안에 7이라는 숫자가 실제로 존재합니다.
- 즉, 변수 이름이 값이 저장된 주소 공간을 직접 가리킵니다.
기본형(primitive type): int, float, double, char, boolean 등
참조 형식 (Reference Type)
FileOutputStream fos = new FileOutputStream("data.txt");
- 변수 fos는 실제 파일 출력 스트림 객체를 가리키는 주소(참조값)만 저장합니다.
- fos 자체에는 객체가 있는 게 아니라, 객체가 있는 곳의 주소가 저장됨.
- 객체는 new 연산자를 통해 Heap 영역에 따로 생성되고,
변수 fos는 그 객체를 참조(Reference)하는 역할만 합니다.
참조형(객체형): String, Scanner, File, Array, 사용자 정의 클래스 등
값 형식의 메모리 구조
int x = 7;
- 메모리 공간 x 안에 숫자 7이 직접 들어있음.
- 그림에서 파란 박스에 7이라는 값이 들어 있는 구조
참조 형식의 메모리 구조
FileOutputStream fos = new FileOutputStream("data.txt");
- 메모리 공간 fos 안에는 객체의 주소값만 있음.
- 실제 객체는 Heap에 따로 존재.
- fos.write('7')을 하면, fos가 가리키는 객체의 기능을 사용하게 됨.
C/C++ 스타일 선언과 자바의 차이 비교
값 변수와 포인터/참조 변수 선언 비교
int x; | 값 변수, 공간에 값 저장 |
int* y; | 포인터 변수, 주소 저장 |
int& z; | 참조 변수 (C++ 전용), 별칭 개념 |
포인터 공간 생성 방식
int* y = new int(4); // 동적 할당 후 주소 저장
int z = *new int(4); // 주소에서 값만 꺼내서 z에 복사 (new int(4)는 메모리 누수됨)
→ 자바에는 포인터 문법이 없지만, 모든 객체가 사실상 힙에 생성되고, 그 주소를 참조형 변수로 다룬다는 점에서 비슷합니다.
자바에서는 어떻게 적용되는가?
자바에서는 아래와 같은 차이가 명확합니다.
값 형식 | int x = 7; | 7 자체 | 메모리에 바로 값 저장 |
참조 형식 | String s = new String("hi"); | 참조 주소 | 객체는 Heap에, 변수는 주소 참조 |
실제 사용 차이 예시
값 형식
int a = 10;
int b = a;
b = 20;
System.out.println(a); // 👉 10
- a의 값은 영향을 안 받음 (복사됨)
참조 형식
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;
arr2[0] = 100;
System.out.println(arr1[0]); // 👉 100
- 배열은 참조형이므로 같은 배열 객체를 공유
마무리 요약
구분 | 값 형식 | 참조 형식 |
저장 위치 | Stack | Stack(주소), Heap(실제 객체) |
변수 안에 저장되는 것 | 값 자체 | 객체의 주소 |
기본 타입 | int, double 등 | 클래스, 배열, 인터페이스 등 |
복사 시 | 값 복사 (독립) | 주소 복사 (공유됨) |
new 필요 여부 | ❌ 없음 | ✅ 필수 (new 사용) |