/**
* Call by Reference
* Call by Reference는 호출 시에 값을 전달하는 것이 아니라 객체의 메모리 주소를 넘겨줍니다.
* 따라서 Call by Reference를 통해 객체의 메모리 주소를 참조하여 데이터를 변경할 수 있습니다.
*
* 참조되는 객체 자체는 메모리의 Heap 영역에 위치하게 되고
* 객체의 메모리 주소를 가리키는 변수는 메모리의 Stack 영역에 위치하게 됩니다.
*/
class CallByReference {
data class Person(var name: String, var age: Int)
fun callByReference() {
/**
* a, b 변수는 Person 객체를 참조하는 변수입니다.
* a, b 변수는 메모리의 Stack 영역에 위치합니다.
* 스택에 위치한 a, b 변수는 객체의 메모리 주소를 저장하고 있습니다.
* a, b가 참조하는 객체 자체는 메모리의 Heap 영역에 위치합니다.
*/
val a = Person("John", 32)
val b = a
println("a.name : ${a.name} / a.age : ${a.age}") // a.name : John / a.age : 32
println("b.name : ${b.name} / b.age : ${b.age}") // b.name : John / b.age : 32
/**
* a, b가 동일한 객체의 메모리 주소를 가리키기 때문에
* b.age를 통해 객체의 age를 변경하면, b가 가리키는 객체의 age 값이 변하게 되고,
* a 변수가 가리키는 객체의 age 값도 변한 것이므로 a.age의 값도 변하게 됨
*/
b.age += 10
println("a.name : ${a.name} / a.age : ${a.age}") // a.name : John / a.age : 42
println("b.name : ${b.name} / b.age : ${b.age}") // b.name : John / b.age : 42
}
}
/**
* Call by Value
* Call by Value는 일반적으로 데이터 타입이 원시 자료형(Primitive Type)일 때 동작하는 방식입니다.
* 원시 자료형은 일반적으로 객체가 아닌 기본적인 데이터 타입으로 취급되고 메모리의 Stack 영역에 위치합니다.
*
* Call by Value는 호출 시에 원시 자료형의 값을 복사해서 넘겨줍니다.
* 복사된 값을 넘겨받은 변수는 메모리의 Stack 영역에 위치하게 됩니다.
* 변수에 저장된 값과 원본의 값은 값이 같을 뿐 메모리 상에서 독립적으로 존재합니다.
*/
class CallByValue {
fun callByValue() {
/**
* 코틀린에서 Int는 대부분의 경우 자동으로 자바의 원시 자료형으로 변환됩니다.
* 때문에 Call by Reference가 아닌 Call by Value로 동작합니다.
* a가 호출한 1은 a와 함께 메모리의 Stack 영역에 위치합니다.
* b는 a의 메모리 주소를 참조하는 것이 아니라 a의 값을 복사해
* 변수 b와 1이 함께 메모리의 Stack 영역에 위치합니다.
*/
var a = 1
var b = a
println("a : $a") // a : 1
println("b : $b") // b : 1
/**
* a와 b는 값만 같을 뿐 서로 다른 객체이므로
* b의 값을 변경해도 a의 값은 영향을 받지 않게 됩니다.
*/
b += 10
println("a : $a") // a : 1
println("b : $b") // b : 11
}
}