-
[Java] Call by Value vs Call by ReferenceJava 2023. 4. 12. 01:09
Call by Value vs Call by Reference
method를 호출할 때, parameter를 전달하는 방법으로는 크게 두 가지가 있다.
- Call by Value
- Call by Reference
🔎 Call by Value
- Call by Value 방식은 함수 호출시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.
- 호출자의 변수와 수신자의 paramenter는 복사된 서로 다른 변수이다.
- 전달받은 인자의 값은 local value의 특성을 가지기 때문에, 함수 내부에서 값이 변경되어도 외부에서의 값은 변경되지 않는다.
🔎 Call by Reference
- Call by Reference 방식은 함수 호출시 전달되는 변수의 참조 주소(reference)를 전달한다.
- 참조를 직접 넘기기 때문에 호출자의 변수와 수신자의 parameter는 완전히 동일한 변수이다.
- 따라서 함수 내부에서 값이 변경되면, argument로 전달된 객체의 값도 함께 변경된다.
❓ Java는 어느 방식을 사용할까?
결론부터 말하자면 java는 Call by Value 방식으로 동작한다.
Java에서 변수를 선언하면 Stack 영역에 할당된다.
이 때, 원시 자료형과 참조 자료형은 저장되는 방식에 차이점이 있다.
원시 자료형 (primitive type): int, short, long, float, double, char, boolean
➡️ Stack 영역에 변수와 함께 저장된다.
참조 자료형 (reference type): Array, 참조 타입
➡️ Heap 영역에 저장되고, Stack 영역에 있는 변수가 객체의 주소값을 갖는다.
package com.example.toyproject; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.*; class User { public String name; public int age; public User(String name, int age) { this.name = name; this.age = age; } } public class CallTest { void modify(User a, User b) { a.age = 30; b = new User("userC", 30); } @Test void test() { User a = new User("userA", 10); User b = new User("userB", 20); modify(a, b); assertThat(a.age).isEqualTo(30); assertThat(b.age).isEqualTo(20); } }
함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 공간이 생성되며, 함수가 종료되면 해당 공간은 사라진다.
위 코드 예제를 보면, 참조 자료형이 함수 내에서 새로운 객체를 할당 받더라도
함수가 종료되는 시점에서 Stack 영역에 할당됐던 변수들은 사라진다.
modify 함수 내에서 a가 가리키는 주소의 객체는
test 함수에서 modify를 호출하기 전에 생성한 객체와 같다.
따라서 modify 함수 내에서 a의 age를 30으로 변경한 것은 그대로 유지된다.
하지만 modify 함수 내에서 만들어진 새로운 객체 (userC)를 가리키는 변수 b는
modify 함수가 종료되면서 사라지므로, test 함수에서 b가 가리키는 객체는 변하지 않는다.
📋 참고 자료
728x90'Java' 카테고리의 다른 글
[Java] 포장 클래스 (Wrapper Class) (0) 2023.04.14 [Java] ==와 equals() 차이 (0) 2023.04.14 [Java] 접근 제어 지시자 (access modifier) (0) 2023.04.14 [Java] 객체 지향 프로그래밍이란? (0) 2023.04.14 [Java] String, StringBuilder, StringBuffer 차이 (0) 2023.04.14