Java Reference
자바에서의 참조 (Java Reference)
- *참조(reference)**는 자바의 중요한 개념 중 하나입니다. 자바에서는 **객체지향 프로그래밍(OOP)**을 기반으로, 객체를 생성하고 메모리 상에서 관리할 때 참조가 사용됩니다. 참조는 객체의 실제 메모리 주소를 가리키는 값으로, 이를 통해 자바 프로그램 내에서 객체에 접근하고 조작할 수 있습니다.
1. 기본 자료형 vs 참조 자료형
자바의 데이터 타입은 크게 **기본 자료형(Primitive Types)**과 **참조 자료형(Reference Types)**으로 나눌 수 있습니다.
1.1 기본 자료형(Primitive Types)
기본 자료형은 값 자체를 저장합니다. 자바에는 8개의 기본 자료형이 있습니다.
자료형 | 크기 | 예시 값 |
---|---|---|
byte |
1 byte | 127, -128 |
short |
2 bytes | 32000, -32000 |
int |
4 bytes | 2147483647, -2147483648 |
long |
8 bytes | 9223372036854775807L |
float |
4 bytes | 3.14f |
double |
8 bytes | 3.14159265358979 |
boolean |
1 bit | true , false |
char |
2 bytes | 'a', 'Z' |
기본 자료형은 값이 변수에 직접 저장되며, 메모리 주소나 참조가 필요하지 않습니다.
1.2 참조 자료형(Reference Types)
참조 자료형은 객체의 메모리 주소를 가리킵니다. 즉, 참조 자료형은 객체 자체가 아닌, 객체가 저장된 메모리 위치를 참조합니다. 자바에서 모든 객체는 참조 자료형을 통해 다뤄집니다.
대표적인 참조 자료형:
- 클래스 (사용자 정의 타입)
- 배열
- 인터페이스
- String
예시: 기본 자료형 vs 참조 자료형
public class Main {
public static void main(String[] args) {
// 기본 자료형
int x = 10;
int y = x; // y는 x의 값을 복사 받음 (값 자체를 저장)
x = 20; // x 값을 변경해도 y에는 영향 없음
System.out.println("x: " + x + ", y: " + y); // x: 20, y: 10
// 참조 자료형
String str1 = "Hello";
String str2 = str1; // str2는 str1이 참조하는 주소를 가리킴 (주소를 참조)
str1 = "World"; // str1이 새로운 객체를 참조하지만, str2는 그대로
System.out.println("str1: " + str1 + ", str2: " + str2); // str1: World, str2: Hello
}
}
설명:
- 기본 자료형은 값 자체를 복사하므로,
x
값을 변경해도y
에 영향을 주지 않습니다. - 참조 자료형은 객체의 참조를 복사하므로,
str1
과str2
는 처음에 같은 객체를 가리킵니다. 하지만str1
이 새로운 객체를 참조하게 되면,str2
는 여전히 원래 객체를 참조합니다.
2. 참조의 개념
2.1 객체 생성과 참조
자바에서 객체를 생성하면, 객체는 **힙 메모리(Heap Memory)**에 저장됩니다. 그 객체에 접근하려면 객체의 **참조(reference)**가 필요합니다. 참조 변수는 객체의 메모리 주소를 저장하며, 이 주소를 통해 객체를 조작할 수 있습니다.
예시: 참조 변수 사용
class Person {
String name;
// 생성자
Person(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
// Person 객체 생성
Person p1 = new Person("Alice");
Person p2 = p1; // p2는 p1이 참조하는 객체를 참조
// p1과 p2는 같은 객체를 참조함
System.out.println(p1.name); // Alice
System.out.println(p2.name); // Alice
// p1의 name 값을 변경
p1.name = "Bob";
System.out.println(p1.name); // Bob
System.out.println(p2.name); // Bob (p2도 p1과 같은 객체를 참조)
}
}
설명:
p1
과p2
는 동일한 객체를 참조하므로,p1
을 통해 객체의 값을 변경하면,p2
를 통해서도 변경된 값을 확인할 수 있습니다. 이는 참조 변수가 객체의 메모리 주소를 저장하고 있기 때문입니다.
3. 참조의 특징
3.1 참조 값 복사
참조 자료형에서 복사는 객체 자체를 복사하는 것이 아니라 **참조 값(주소)**를 복사하는 것입니다. 즉, 여러 참조 변수가 동일한 객체를 참조할 수 있습니다.
3.2 null
참조
자바에서는 참조 변수가 아무것도 가리키지 않도록 **null
**을 사용할 수 있습니다. null
참조는 객체가 메모리에 존재하지 않음을 의미합니다.
public class Main {
public static void main(String[] args) {
Person p1 = null; // 참조 변수가 아무 객체도 가리키지 않음
if (p1 == null) {
System.out.println("p1은 null을 참조합니다.");
}
}
}
3.3 ==
연산자와 equals()
메서드
자바에서 ==
연산자는 **참조 값(메모리 주소)**가 같은지를 비교합니다. 반면, equals()
메서드는 객체의 내용이 같은지를 비교합니다. 이 차이를 이해하는 것이 중요합니다.
public class Main {
public static void main(String[] args) {
String s1 = new String("Hello");
String s2 = new String("Hello");
// ==는 참조 값 비교
System.out.println(s1 == s2); // false (서로 다른 객체)
// equals()는 객체의 값 비교
System.out.println(s1.equals(s2)); // true (문자열 값은 동일)
}
}
설명:
s1
과s2
는 다른 객체를 참조하고 있으므로,==
연산자는false
를 반환합니다.- 두 문자열의 값은 동일하므로,
equals()
메서드는true
를 반환합니다.
4. 참조의 메모리 관리 (Garbage Collection)
자바에서는 **가비지 컬렉터(Garbage Collector)**가 참조되지 않는 객체를 자동으로 제거하여 메모리를 관리합니다. 객체가 더 이상 참조되지 않으면 가비지 컬렉터에 의해 힙 메모리에서 제거됩니다. 이를 통해 자바는 메모리 관리를 자동으로 처리합니다.
4.1 가비지 컬렉션의 동작 예시
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice");
Person p2 = new Person("Bob");
// p1을 null로 설정하여 "Alice" 객체를 참조하지 않음
p1 = null;
// 가비지 컬렉터는 p1이 참조하던 객체를 메모리에서 제거 가능
System.out.println(p2.name); // Bob
}
}
설명:
p1
이null
이 되면서, "Alice" 객체는 더 이상 참조되지 않으므로 가비지 컬렉터에 의해 제거될 수 있습니다.
5. final
참조 변수
final
키워드를 사용하면 참조 변수가 한 번 초기화된 후에는 다른 객체를 참조할 수 없게 됩니다. 하지만, 참조하는 객체의 내용은
변경할 수 있습니다.
5.1 final
참조 변수 예시
class Person {
String name;
Person(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
final Person p = new Person("Alice");
// 참조된 객체의 내용은 변경 가능
p.name = "Bob";
System.out.println(p.name); // Bob
// p = new Person("Charlie"); // 오류: p는 새로운 객체를 참조할 수 없음
}
}
설명:
p
는 final로 선언되
었기 때문에 다른 객체를 참조할 수는 없지만, 객체의 내부 상태는 변경 가능합니다.
요약
- 참조 자료형은 객체의 메모리 주소를 가리키는 값으로, 객체를 참조하여 접근할 수 있습니다.
- 자바에서
==
연산자는 **참조 값(주소)**를 비교하고, **equals()
*는 객체의 내용을 비교합니다. - 가비지 컬렉션은 참조되지 않는 객체를 메모리에서 제거하는 역할을 합니다.
final
참조 변수는 한 번 초기화된 후 다른 객체를 참조할 수 없지만, 참조된 객체의 내용은 변경할 수 있습니다.
참조 개념은 자바의 객체 지향 프로그래밍에서 중요한 역할을 하며, 메모리 관리 및 객체 비교에 깊이 관여합니다.