본문 바로가기
language/java

Java 참조 타입(Reference Type)과 객체 참조 완벽 이해하기

by 죄니안죄니 2026. 5. 26.
반응형

Java 참조 타입(Reference Type)과 객체 참조 완벽 이해하기

Java를 공부할 때 정말 많이 헷갈리는 개념이 바로:

참조 타입(Reference Type)

입니다.

특히 초보 시절에는:

 
User a = new User();
User b = a;
 

이 코드가:

객체 복사인가?
주소 복사인가?
 

매우 헷갈립니다.

실무에서도:

  • 객체 수정 Side Effect
  • 얕은 복사(Shallow Copy)
  • 깊은 복사(Deep Copy)
  • Collection 복사 문제
  • 동시성 문제

까지 전부 참조 구조와 연결됩니다.

이번 글에서는:

  • 참조 타입이란 무엇인가
  • 객체 참조 구조
  • Java 메모리 흐름
  • Call By Value 진실
  • 얕은 복사 / 깊은 복사

까지 JVM 메모리 관점으로 깊게 정리해보겠습니다.


1. Java 타입은 크게 2가지

Java 타입은:


구분 종류
Primitive Type int, long, double 등
Reference Type 객체 타입

2. Primitive Type

primitive는:

값을 직접 저장하는 타입

입니다.

예시:

 
int a = 10;
 

메모리:

Stack:
a = 10
 

즉 값 자체 저장.


3. Reference Type

참조 타입은:

객체 주소(reference)를 저장하는 타입

입니다.

예시:

 
User user = new User();
 

4. 메모리 구조

Stack:
user -> 0x1000

Heap:
0x1000 -> User 객체
 

즉:

Stack = 주소값
Heap = 실제 객체
 

입니다.


5. 가장 중요한 핵심

매우 중요합니다.

 
User user
 

이 변수는:

객체 자체가 아니다
 

즉:

객체 위치를 가리키는 참조값(reference)
 

입니다.


6. 객체 참조 예시

 
User a = new User();
User b = a;
 

메모리:

Stack:
a -> 0x1000
b -> 0x1000

Heap:
0x1000 -> User 객체
 

즉:

같은 객체 참조 중
 

입니다.


7. 그래서 한쪽 수정 시 영향 발생

 
b.name = "Kim";
 

하면:

 
a.name
 

도 변경됨.

왜냐하면:

같은 Heap 객체
 

를 바라보기 때문.


8. Java는 포인터인가?

Java는:

직접 포인터는 숨김
 

구조입니다.

하지만 내부적으로는 사실상:

reference 기반 주소 구조
 

사용.


9. 왜 포인터를 숨길까?

C/C++처럼 직접 메모리 접근 허용하면:

  • 메모리 오염
  • 시스템 충돌
  • 보안 문제

위험 증가.

Java는:

안전한 reference 추상화
 

사용.


10. null이란?

 
User user = null;
 

의미:

참조 대상 없음
 

즉:

아무 객체도 가리키지 않음
 

상태.


11. NullPointerException 원인

 
user.name
 

실행 시:

참조 대상 없음
 

→ NullPointerException 발생.


12. 객체 비교 ==

매우 중요합니다.

 
a == b
 

의미:

같은 객체 참조인가?
 

입니다.


13. 예시

 
User a = new User();
User b = new User();
 

결과:

 
a == b
 

false
 

왜냐하면:

Heap 객체가 서로 다름
 

14. equals()와 차이

 
equals()
 

는:

논리적 동등성 비교
 

입니다.

즉:

  • 값 비교 가능
  • 내용 비교 가능

15. String 비교 실수

안 좋은 예:

 
String a = new String("Java");
String b = new String("Java");

a == b
 

결과:

false
 

왜냐하면:

다른 객체
 

이기 때문.


16. String equals()

 
a.equals(b)
 

true
 

내용 비교 수행.


17. 메서드 호출 시 객체 전달

예시:

 
change(user);
 

많이 헷갈리는 부분.


18. Java는 Call By Value

매우 중요합니다.

Java는:

무조건 Call By Value

입니다.


19. 그럼 왜 객체 변경이 될까?

예시:

 
void change(User user) {
    user.name = "Kim";
}
 

이유:

reference 값 자체를 복사
 

하기 때문.


20. 메모리 흐름

원본:
user -> 0x1000

복사:
parameter -> 0x1000
 

즉:

같은 객체 참조
 

중.


21. 하지만 참조 자체 변경은 영향 없음

 
void test(User user) {

    user = new User();
}
 

이 경우:

지역 변수 reference만 변경
 

입니다.

원본 영향 없음.


22. 매우 중요한 차이


동작 원본 영향
객체 내부 수정 O
참조 재할당 X

23. 얕은 복사(Shallow Copy)

얕은 복사는:

reference만 복사

하는 것.

예시:

 
User b = a;
 

24. 얕은 복사 메모리 구조

a -> 0x1000
b -> 0x1000
 

즉:

같은 객체 공유
 

25. 얕은 복사 문제

한쪽 수정 시:

다른 쪽 영향 발생
 

가능.

실무에서 매우 중요.


26. 깊은 복사(Deep Copy)

깊은 복사는:

새로운 객체를 새로 생성하여 복사

하는 것.


27. 깊은 복사 예시

 
User copy = new User();

copy.name = original.name;
 

메모리:

original -> 0x1000
copy     -> 0x2000
 

28. Collection 얕은 복사 문제

대표 사례:

 
List<User> copy =
    new ArrayList<>(original);
 

주의:

List만 새 객체
내부 User는 같은 참조
 

입니다.


29. 실무에서 매우 많이 터지는 문제

대표 사례:

  • DTO 수정 영향
  • 캐시 데이터 오염
  • 멀티스레드 공유 문제
  • Collection 내부 객체 변경

30. Immutable Object가 중요한 이유

불변 객체는:

객체 수정 자체 불가능
 

즉:

  • Side Effect 감소
  • Thread-safe 향상

가능.


31. String은 왜 immutable일까?

대표 이유:

공유 안전성
 

입니다.

예:

 
String a = "Java";
String b = a;
 

같은 객체 공유 가능.


32. 참조 타입 종류

대표 참조 타입:


타입 예시
클래스 User
배열 int[]
인터페이스 List
enum Role

33. 배열도 참조 타입

 
int[] arr = new int[3];
 

메모리:

Stack:
arr -> 0x1000

Heap:
배열 객체
 

34. 다형성과 reference

예시:

 
Animal animal = new Dog();
 

Stack:

animal -> Dog 객체 주소
 

즉:

참조 타입은 부모
실제 객체는 자식
 

가능.


35. 실무에서 자주 하는 실수

1) 객체 복사와 참조 복사 혼동

 
User b = a;
 

객체 복사 아님.


2) equals 대신 == 사용

특히 String 비교 문제 매우 흔함.


3) Collection 복사 시 깊은 복사 착각

실제로는 대부분 shallow copy.


36. 핵심 흐름 요약

reference 변수
↓
Heap 객체 주소 저장
↓
실제 객체 접근
 

37. 가장 중요한 핵심 한 줄

Java 객체 변수는
객체 자체가 아니라
reference를 저장한다
 

38. 정리

참조 타입(reference type)은 단순 문법 개념이 아닙니다.

실제로는:

  • 객체 메모리 구조
  • JVM Heap/Stack
  • 객체 공유
  • 얕은 복사/깊은 복사
  • Side Effect
  • GC

전체와 연결되는 매우 중요한 개념입니다.

특히 실무에서는:

  • reference 구조
  • equals vs ==
  • shallow/deep copy
  • immutable 객체

를 정확히 이해하는 것이 매우 중요합니다.

다음 글에서는:

String Pool 원리

를 intern(), 문자열 최적화, immutable 구조, JVM Constant Pool까지 포함해서 깊게 정리해보겠습니다.

반응형

댓글