본문 바로가기

Java/Java

(JAVA) CallByValue & CallByReference

CallByValue와 CallByReference는 메서드에서 인자 값을 받을 때 어떠 한식으로 값을 받아 올 것 인가에 대한 방식이다.
두 방식은 값에 의한 호출인가 혹은 참조에 의한 호출 인가로 구별할 수 있다.

 

CallByValue

메서드 호출 시점에 사용하는 인자에 저장되어있는 값을 복사하여 보낸다.

 

 

예제를 들어서 설명해보자!

/**
 * Project : EffectiveStudy
 *
 * @author : jwdeveloper
 * @comment :
 * Time : 4:31 오후
 */
public class CallByValue {
    public static void swap(int n1, int n2) {
        int temp = n1;
        n1 = n2;
        n2 = temp;
    }

    public static void main(String[] args) {
        int n1 = 2;
        int n2 = 5;

        swap(n1,n2);

        System.out.println(n1);
        System.out.println(n2);
    }
}

위의 코드의 실행 결과는 아래와 같이 값이 바뀌지 않았다.

실행 결과

값만 복사해서 넘겼기 때문에 main 함수에서 사용되는 변수에는 영향을 주지 않는다.

조금 더 구체적으로 말하자면  swap() 함수를 호출하는 시점에는 temp 변수와 n1, n2 가 새롭게 스택에 쌓이게 된다.

(기존의 n1, n2는 Scope이 다르기 때문에 완전히 다른 존재 이다.)

 

} 괄호를 만나는 순간 해당 함수에서 생겨난 stack의 변수들은 POP이 되며 다시 기존 Stack에 쌓였던 n1,n2로 돌아오게된다.

(이때 n1, n2에는 값의 변화가 없음을 볼 수 있다.)


Call By Reference

  • call-by-reference 참조에 의한 호출방식은 함수 호출 시 인자로 전달되는 변수의 레퍼런스를 전달한다. (해당 변수를 가리킨다.)
  • 따라서 함수 안에서 인자의 값이 변경되면, 아규먼트로 전달된 객체의 값도 함께 변경된다.

예시 (C 언어)

#include <iostream>

using namespace std;


void sum(int* a, int* b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    
    int a1 = 10;
    int a2 = 20;
    
    sum(&a1, &a2);
    cout << "a1: " << a1 << " a2: " << a2 << endl;

    return 0;
}

실행결과 

변수의 래퍼런스를 전달받아서 해당 래퍼런스가 참조하고 있는 메모리의 변수 값을 바꾸어 준다.

 

반면 JAVA에서는 Call By Reference가 존재할까?

결론부터 말하자면  존재하지 않는다.😅

 

예시 (JAVA)

/**
 * Project : EffectiveStudy
 *
 * @author : jwdeveloper
 * @comment :
 * Time : 4:49 오후
 */
public class CallByReference2{

    public static void swap(Person person0, Person person1) {
        String temp = person0.getName();
        person0.setName(person1.getName());
        person1.setName(temp);
    }


    public static void main(String[] args) {
        Person person0 = new Person("junwoo", 30);
        Person person1 = new Person("jwdeveloper", 30);
        
        swap(person0, person1);
    }
}

실행결과

 

결과가 바뀌긴 바뀌었다!

그렇다면 자바도 Call By Reference 가 존재한다고 생각해도 되는구나!

 

가 아니다.

 

 

왜냐면 Call By Reference는 주소를 가리키는 래퍼런스 아규먼트로 전달하는 게 아닌 실제 주소를 전달해야 한다.

위의 C 예시에서는 포인터를 사용해 실제 메모리 주소를 직접적으로 참조하고 있으니 C언어에는 Call By Reference가 존재하는 것이 분명하지만 자바에서는 실제 메모리 주소를 직접적으로 참조할 수 있는 포인터와 같은 개념이 없기 때문에 존재하지 않는다고 말할 수 있다.


References

https://yaboong.github.io/java/2018/05/26/java-memory-management/

 

자바 메모리 관리 - 스택 & 힙

개요 Java 에서 메모리 관리는 어떻게 이루어지는지 알아보기 위함. Stack 과 Heap 영역 각 역할에 대해 알아본다. 간단한 코드예제와 함께 실제 코드에서 어떻게 Stack 과 Heap 영역이 사용되는지 살펴

yaboong.github.io

https://multifrontgarden.tistory.com/87

 

call by value, call by reference

메서드를 호출할때 호출 하는 메서드가 인자를 필요로 하는경우 () 안에 인자를 넣어 호출한다. 이때 메서드에서 파라미터를 받아 사용할때 호출하는 방법이 2가지가 있는데 그것이 call by value, c

multifrontgarden.tistory.com

https://blog.naver.com/gngh0101/221160889447

 

Java Call by value 와 Call by reference 쉽게 이해하기

Java Call by value 와 Call by reference 쉽게 이해하기 자바의 Call by value 와 Call by reference...

blog.naver.com

http://wonwoo.ml/index.php/post/1679

 

java는 call by value? call by reference? - 머루의개발블로그

오늘도 역시 java에 대해서 이야기 해볼려고 한다. java로 먹고 살아야 하니.. call by value와 call by reference 오늘 내용은 제목에도 있다시피 java는 call by value?, call by reference? 를 알아볼 예정이다. 그 전

wonwoo.ml

https://yaboong.github.io/java/2018/05/26/java-memory-management/

 

자바 메모리 관리 - 스택 & 힙

개요 Java 에서 메모리 관리는 어떻게 이루어지는지 알아보기 위함. Stack 과 Heap 영역 각 역할에 대해 알아본다. 간단한 코드예제와 함께 실제 코드에서 어떻게 Stack 과 Heap 영역이 사용되는지 살펴

yaboong.github.io