JShell은 Java 9에 도입된 대화형(REPL) 도구로, 사용자가 입력한 코드를 즉시 평가하고 그 결과를 화면에 출력해 줍니다. 별도의 컴파일 과정 없이 자바 코드를 한 줄씩 실행하며 학습하고 테스트할 수 있어 매우 유용합니다.
참조 타입이란?
기본형(primitive type)과 달리 참조 타입(reference type)은 값을 직접 저장하지 않습니다. 대신 실제 값이 저장되어 있는 메모리 주소(address)를 저장합니다. 즉, 참조 타입 변수는 데이터가 들어 있는 다른 메모리 위치를 가리키는 포인터 역할을 합니다.
Java에서 대표적인 참조 타입으로는 String, 배열(array), 클래스(class), 인터페이스(interface) 등이 있습니다.
클래스 객체 생성과 힙 메모리
아래 코드 스니펫에서 Animal 클래스의 새 인스턴스를 생성하면, 해당 객체는 힙(heap) 메모리에 생성됩니다. new Animal() 구문이 힙 위에 객체를 만들며, 출력 결과인 Animal@73846619는 이 객체가 힙의 73846619번 주소에 저장되어 있음을 의미합니다.
예제 1
jshell> class Animal {
...> }
| created class Animal
jshell> Animal dog = new Animal();
dog ==> Animal@73846619참조 변수에 객체 참조 저장하기
다음 예제에서는 두 개의 새로운 Animal 객체가 힙에 생성됩니다. 각 객체의 메모리 위치(참조)는 dog와 cat이라는 참조 변수에 각각 저장됩니다.
Java에서 모든 클래스는 참조 타입입니다. 기본형(primitive) 변수를 제외한 모든 인스턴스와 객체는 힙에 저장되며, 객체를 가리키는 참조만 dog, cat과 같은 참조 변수에 보관됩니다.
예제 2
jshell> class Animal {
...> int id;
...> public Animal(int id) {
...> this.id = id;
...> }
...> }
| created class Animal
jshell> Animal dog = new Animal(10);
dog ==> Animal@6adede5
jshell> Animal cat = new Animal(20);
cat ==> Animal@5025a98f기본형 변수의 값 복사와 비교
반면 아래 코드에서 j = i는 변수 i의 값 자체를 j에 복사합니다. 이후 j의 값을 변경하더라도 i에는 아무런 영향을 주지 않습니다. 기본형 변수끼리 비교할 때는 객체의 참조가 아니라 실제 값이 비교됩니다.
예제 3
jshell> int i = 5; i ==> 5 jshell> int j; j ==> 0 jshell> j = i; j ==> 5 jshell> j = 10; j ==> 10 jshell> i; i ==> 5 jshell> i == j; $11 ==> false jshell> j = 5; j ==> 5 jshell> i == j; $13 ==> true
정리
JShell을 활용하면 참조 타입과 기본형 타입의 동작 차이를 손쉽게 실험해 볼 수 있습니다. 핵심을 요약하면 다음과 같습니다.
- 참조 타입: 객체는 힙에 생성되고, 변수에는 객체의 메모리 주소(참조)가 저장됩니다.
- 기본형 타입: 변수에 값이 직접 저장되며, 대입 시 값이 복사됩니다.
- 비교 연산: 기본형은 값 자체를 비교하고, 참조형은 == 연산 시 참조(주소)를 비교합니다.