본문 바로가기
공부이야기/Java

[Java] 자바는 Call by value? Call by reference?

by coderoom 2021. 4. 29.

 

 

Call by value

변수의 값을 복사해 함수의 매개변수로 전달하는 것.

때문에 넘겨받은 함수의 인자값을 아무리 변경해도 외부에서는 그 값이 변경되지 않는다.

 

 

 

자바의 메소드 호출 방식에 대해 아래 예제를 통해 자세히 살펴보자.

 

 

Example 1)

swap() 함수를 통해 값을 변경한 듯 하지만 출력 결과는 swap전과 동일하다.

이는 x, y에는 a, b의 메모리 주소가 아니라 값만 복사되었기 때문이다.

public class Test {
	public static void swap(int x, int y) {
    	int temp = x;
        x = y;
        y = temp;
    }
    
    public static void main(String[] args) {
    	int a = 10;
        int b = 20;
        
        System.out.println("before: a = " + a + ", b = " + b);
        swap(a, b);
        System.out.println("after: a = " + a + ", b = " + b);
    }
}

Result

before: a = 10, b = 20
after: a = 10, b = 20

 

 

Example 2)

change() 함수를 통해 x에 새로운 객체를 대입했음에도 출력 결과는 change전과 동일하다.

자바는 객체를 메소드로 넘길 때 객체를 참조하는 지역변수의 실제 주소를 넘기는 것이 아니라 그 지역변수가 가리키고 있는 힙 영역의 객체를 가리키는 새로운 지역변수를 생성하여 그것이 같은 객체를 가리키도록 한다.

public class Test {
	public static void change(NumberClass x) {
    	NumberClass tmp = new NumberClass(20);
        x = tmp;
    }
    
    public static void main(String[] args) {
    	NumberClass a = new NumberClass(10);
        
        System.out.println("before: a = " + a.num);
        change(a);
        System.out.println("after: a = " + a.num);
    }
}

class NumberClass {
	int num;
    
    NumberClass(int num) {
    	this.num = num;
    }
}

Result

before: a = 10
after: a = 10

 

 

Example 3)

이번엔 change() 함수에서 객체의 필드 값을 변경해 보았다. 출력 결과는,다른 예제들과 달리 값이 변경되었다.

참조 값을 직접 바꾼 것이 아니라 참조 값의 내부 값을 변경하였기 때문에 이러한 결과가 나온 것이다.

(이런 결과로 인해 자바는 Call by reference라는 오해를 받는다.)

public class Test {
	public static void change(NumberClass x) {
    	x.num = 20;
    }
    
    public static void main(String[] args) {
    	NumberClass a = new NumberClass(10);
        
        System.out.println("before: a = " + a.num);
        change(a);
        System.out.println("after: a = " + a.num);
    }
}

class NumberClass {
	int num;
    
    NumberClass(int num) {
    	this.num = num;
    }
}

Result

before: a = 10
after: a = 20

 

 

 

 

 

Call by reference

변수를 참조할 수 있는 주소값을 함수의 매개변수로 전달하는 것.

C언어의 포인터(*)

void swap(int *num1, int *num2) {
	int temp = *num1;
    *num1 = *num2;
    *num2 = temp;
}

 

 

 

 

포인터가 익숙하신 C 사용자분들에게는 Call by value/reference를 구분한다는게 자연스러울거라 생각된다. (나도 그랬으니..!)

하지만 자바를 공부하다보니 자바는 이를 구분하는게 어울리지 않는 듯한 느낌이다. 

그럼에도 실제 자바를 사용하다보면 한번쯤은 짚어 주고 가야하는 부분이기에 쓱- 알고 가면 좋을 듯 하다.

 - mushroong

 

 

 

 

 

참고 링크

 

 

 

 


 

 

댓글