기본형과 참조형
- 김영한님의 실전 자바 강의 중 기본형과 참조형 챕터를 학습하며 자바의 기본형과 참조형의 차이, 메모리 관리 방식(Stack vs Heap), 그리고 변수 대입 시 값 복사와 참조값 복사의 차이를 정리함
기본형과 참조형의 차이
기본형 (Primitive Type)
- 사용하는 값을 변수에 직접 저장하는 데이터 타입
- 종류
- 정수형
byte,short,int,long
- 실수형
float,double
- 문자형
char
- 논리형
boolean
- 정수형
- 특징
- 소문자로 시작함
- 자바 언어 차원에서 제공하며 개발자가 새로 정의할 수 없음
- 사칙 연산(
+,-등)이 가능함 null값을 가질 수 없음 (반드시 초기화 필요)
참조형 (Reference Type)
- 실제 값이 아닌 객체의 위치(참조값, 주소)를 저장하는 데이터 타입
- 종류
- 배열(
[]), 클래스(Class), 인터페이스(Interface) 등 - 기본형 8가지를 제외한 모든 것
- 배열(
- 특징
- 대문자로 시작함 (클래스명)
- 개발자가
class키워드로 직접 정의할 수 있음 - 참조값 자체로는 연산이 불가능함
- 객체 내부의 기본형 변수에 접근해서 계산해야 함
null값을 가질 수 있음 (참조하는 대상이 없음)
변수 대입의 대원칙
- “자바는 항상 변수의 값을 복사해서 대입한다”
- 이 원칙은 기본형과 참조형 모두에게 동일하게 적용됨
- 기본형
- 변수에 들어있는 실제 값을 복사
- 참조형
- 변수에 들어있는 참조값(주소)을 복사
- 기본형
기본형의 대입 (값 복사)
- 원본 변수의 값이 변경되어도 복사본에는 전혀 영향을 주지 않음 (독립적)
-
예시 코드
1 2 3 4 5 6 7
int hp1 = 100; int hp2 = hp1; // hp1의 값 100이 복사되어 hp2에 대입됨 hp1 = 50; // hp1의 값만 50으로 변경됨 System.out.println("hp1 = " + hp1); // 50 System.out.println("hp2 = " + hp2); // 100 (영향 없음)
참조형의 대입 (참조값 복사)
- 실제 객체(인스턴스)가 복사되는 것이 아니라, 객체를 가리키는 주소만 복사됨
- 결과적으로 두 변수가 하나의 인스턴스를 공유하게 됨
-
메모리 구조

-
예시 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Adventurer 클래스 정의 public class Adventurer { int level; } Adventurer player1 = new Adventurer(); // 참조값 x001 생성 player1.level = 1; Adventurer player2 = player1; // player1의 참조값(x001)이 player2에 복사됨 // player1을 통해 레벨업을 했지만 player1.level = 5; // player2도 같은 곳(x001)을 바라보므로 값이 바뀐 것으로 보임 System.out.println("player1 level = " + player1.level); // 5 System.out.println("player2 level = " + player2.level); // 5 (함께 변경됨)
메서드 호출과 파라미터 전달
- 메서드 호출 시에도 “값 복사“의 대원칙은 동일함
- 매개변수(Parameter)로 무엇이 전달되느냐에 따라 사이드 이펙트 발생 여부가 결정됨
기본형 전달 (Side Effect 없음)
- 메서드로 기본형 데이터를 전달하면 값만 복사되어 넘어감
- 메서드 내부에서 파라미터 값을 아무리 변경해도 호출자의 원본 변수에는 영향이 없음
-
예시 코드
1 2 3 4 5 6 7 8 9
public static void main(String[] args) { int exp = 100; resetExp(exp); System.out.println("main exp = " + exp); // 여전히 100 (변경되지 않음) } static void resetExp(int x) { x = 0; // 매개변수 x의 값만 0으로 바뀜 }
참조형 전달 (Side Effect 있음)
- 메서드로 참조형 데이터를 전달하면 주소(참조값)가 복사되어 넘어감
- 메서드 내부에서 참조값을 통해 객체에 접근하여 필드를 수정하면, 원본 객체 자체가 수정됨
-
메서드 호출 흐름

-
예시 코드
1 2 3 4 5 6 7 8 9 10 11 12
public static void main(String[] args) { Adventurer player = new Adventurer(); player.level = 10; levelUp(player); System.out.println("main player level = " + player.level); // 11 (변경됨!) } static void levelUp(Adventurer a) { // 넘어온 참조값(주소)을 통해 실제 객체에 접근하여 값을 변경 a.level++; }
변수의 초기화
멤버 변수 (필드)
- 클래스 내부에 선언된 변수
- 인스턴스(
new) 생성 시 자동으로 초기화됨 - 자동 초기화 규칙
- 숫자형
int,long,double등은0또는0.0
- 논리형
boolean은false
- 참조형
String, 객체, 배열은null
- 숫자형
지역 변수
- 메서드 내부에 선언된 변수 (매개변수 포함)
- 자동으로 초기화되지 않음
- 초기화하지 않고 사용하려 하면 컴파일 에러 발생 (
Variable 'x' might not have been initialized)
null과 Garbage Collection
null의 의미
- 참조형 변수에서 “가리키는 객체가 없다“는 것을 나타내는 값
- 아직 연결할 객체가 정해지지 않았거나, 기존 객체와의 연결을 끊을 때 사용
Garbage Collection (GC)
- 아무도 참조하지 않는 인스턴스의 처리 방식
- 참조형 변수에
null을 할당하거나 변수의 스코프가 끝나서 참조가 끊기면, 해당 인스턴스에 접근할 방법이 사라짐 - 자바의 JVM(GC)은 이러한 “버려진 객체”를 자동으로 감지하여 메모리에서 제거함
- 개발자가 C/C++처럼 직접 메모리를 해제(
free)할 필요가 없음 -
GC 동작 과정

NullPointerException
null값을 가진 참조 변수에 접근(.dot)하려고 할 때 발생함- 즉, “주소가 없는 곳을 찾아가려고 할 때” 발생하는 문제
단순 발생 예시
- 아직 객체가 생성되지 않은 상태에서 접근할 때 발생
-
예시 코드
1 2
Adventurer player = null; // 아직 캐릭터가 생성되지 않음 player.level = 1; // 예외 발생 (null.level 접근 불가)
멤버 변수에서의 발생
- 클래스 내부의 참조형 멤버 변수가 초기화되지 않아
null상태일 때 자주 발생함 -
예시 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
public class Guild { Adventurer master; // 참조형이므로 자동 초기화값은 null int guildLevel; } public static void main(String[] args) { Guild myGuild = new Guild(); // myGuild 자체는 생성되었지만, 내부의 master는 아직 null임 System.out.println(myGuild.guildLevel); // 0 (정상) // NullPointerException 발생 // myGuild.master가 null인데 그 안의 level에 접근하려 함 System.out.println(myGuild.master.level); }
해결 방법
- 참조형 변수를 사용하기(
.을 찍기) 전에 반드시 유효한 객체를 참조하고 있는지 확인해야 함 - 필요한 시점에 객체를 생성(
new)하여 할당해야 함 -
해결 예시 코드
1 2 3
Guild myGuild = new Guild(); myGuild.master = new Adventurer(); // 객체 생성 후 연결 System.out.println(myGuild.master.level); // 정상 동작
요약 정리
변수 대입의 대원칙
- 자바의 값 복사 원칙
- 자바에서 변수의 대입은 항상 값을 복사해서 전달함
- 기본형은 실제 값을 복사함
- 참조형은 객체의 위치를 가리키는 참조 값(주소)을 복사함
메서드 호출과 Side Effect
- 기본형 파라미터
- 값만 복사되므로 원본에 영향이 없음
- 참조형 파라미터
- 참조값이 복사되므로 원본 객체를 변경할 수 있음(Side Effect)
Null과 메모리 관리
- NullPointerException
- 참조할 대상이 없음을 의미하며, 이 상태에서 접근하면
NullPointerException이 발생함
- 참조할 대상이 없음을 의미하며, 이 상태에서 접근하면
- Garbage Collection
- 참조가 끊긴 객체는 가비지 컬렉터가 자동으로 메모리에서 정리해줌
연습 문제
-
Java에서 기본형과 참조형 변수가 값을 저장하는 방식의 가장 큰 차이점은 무엇일까요?
a. 기본형은 값 직접 저장, 참조형은 주소 저장
- 기본형 변수는 실제 사용 값을 바로 저장하지만, 참조형 변수는 객체가 있는 메모리 주소를 저장해서 그 주소로 접근함
-
Java에서 변수 대입(예:
a = b;) 시, 실제로 복사되는 데이터는 무엇일까요?a. 기본형은 값 자체가, 참조형은 메모리 주소가 복사된다
- 자바의 모든 대입은 변수 안에 저장된 ‘값’ 자체를 복사함
- 기본형은 실제 값이, 참조형은 객체의 주소 값이 복사되는 거임
-
메서드에 변수를 전달할 때, 기본형과 참조형 변수의 동작 차이는 무엇일까요?
a. 기본형 변경은 외부 영향X, 참조형 변경은 외부 영향O
- 기본형은 값만 복사되어 원본과 분리되지만, 참조형은 주소가 복사되어 같은 객체를 가리키므로 객체 내용 변경 시 원본에 영향 줌
-
null이 의미하는 것은 무엇이며, 주로 어떤 타입의 변수에 사용할까요?a. 참조할 대상이 없음, 참조형 변수
null은 참조형 변수가 현재 어떤 유효한 객체도 가리키고 있지 않다는 특별한 상태를 나타냄- 기본형 변수에는
null을 대입할 수 없음
-
Java에서
NullPointerException은 주로 언제 발생할까요?a. null 값을 가진 참조 변수로 멤버 접근 시
- 참조 변수가 null인 상태에서 점(.) 이음을 해당 객체의 필드나 메서드에 접근하려고 시도할 때 이 예외가 발생함
- 대상이 없는데 접근하려 한 거라 에러가 남