자바에서 Pass by Refrence 와 Pass by Value

Jstorm에서 가져온 내용입니다.

며칠전 Jstorm세미나를 하다가 한 친구가 자바는
Pass by Value인지 아니면 Pass by Reference인지를 물어봤습니다.
그래서 저는 두서없이 primitive type은 Pass by Value이고
객체는 Pass by Reference라고 대충 말해줬습니다.
하지만 사실 엄밀한 의미에서 말하면 모든 자바에서의 값넘김은
Pass by Value이죠... 어쨌든 그 미묘한 차이를 이해하는 것은
의외로 상당히 중요할 듯 싶어서 외국 문서 몇개를 뒤져서
쉽게 설명이 가능하도록 글을 써봅니다.

자바에서의 Pass by Value의 의미란?

아래 예제를 먼저 볼까요?

class Test { 
        public static void main(String args[]) { 
                int val; 
                StringBuffer sb1, sb2; 
                val = 10; 
                sb1 = new StringBuffer("apples"); 
                sb2 = new StringBuffer("pears"); 
                System.out.println("val is " + val); 
                System.out.println("sb1 is " + sb1); 
                System.out.println("sb2 is " + sb2); 
                System.out.println(""); 
                System.out.println("calling modify"); 
                //All parameters passed by value 
                modify(val, sb1, sb2); 
                System.out.println("returned from modify"); 
                System.out.println(""); 
                System.out.println("val is " + val); 
                System.out.println("sb1 is " + sb1); 
                System.out.println("sb2 is " + sb2); 
        } 
        public static void modify(int a, StringBuffer r1, StringBuffer r2) { 
                System.out.println("in modify..."); 
                a = 0; 
                r1 = null; 
                //1 
                r2.append(" taste good"); 
                System.out.println("a is " + a); 
                System.out.println("r1 is " + r1); 
                System.out.println("r2 is " + r2); } }

아래는 결과입니다.

val is 10
sb1 is apples
sb2 is pears
 
calling modify
in modify...
a is 0
r1 is null
r2 is pears taste good
returned from modify
 
val is 10
sb1 is apples
sb2 is pears taste good

예제코드에서는 세개의 변수를 선언하고 있습니다. 하나는 int이고
두개는 객체이지요. 일단 각 변수들을 초기화하고 출력합니다.
그리고선 그 변수들은 modify함수에 인자값으로 넘어가게 됩니다.

그러면 modify함수는 인자로 넘어온 세 값들을 변경시키고는 출력합니다.
main으로 다시 돌아오면 세 변수들은 다시 한번 출력합니다.

int형인 val값은 당연히 pass by value이므로 바뀌지 않았습니다.
그런데 이상한 것은 sb1객체입니다. 위에서도 제가 한 친구에게 말했듯
자바에서 객체는 pass by Reference라고 했는데 왜 안바뀌었을까요?
사실 자바에서 객체는 참조(Reference)값의 복사본을 Pass by Value로
넘긴답니다. 따라서 modify함수에서 sb1의 참조값을 변경하더라도
main으로 돌아오면 그 참조값은 예전 그대로 살아있는 것입니다.

그러면 두번째 객체 참조값인 sb2를 살펴봅시다. 비록 sb2의 참조값의
복사본이 modify에 넘겨졌지만 어쨌든 두 객체는 같은 곳을 참조하고
있기때문에 객체를 변화시키는 일련의 행위들은 동일하게 작용하게
되는 것이죠.

그러면 이제 자바를 이용해서 swap 함수를 만들어봅시다.
아래 예제가 잘 실행이 될지 생각해보세요.

class Swap { 
        public static void main(String args[]) { 
                Integer a, b; 
                a = new Integer(10); 
                b = new Integer(50); 
                System.out.println("before swap..."); 
                System.out.println("a is " + a); 
                System.out.println("b is " + b); 
                swap(a, b); 
                System.out.println("after swap..."); 
                System.out.println("a is " + a); 
                System.out.println("b is " + b); 
        } 
        public static void swap(Integer a, Integer b) { 
                Integer temp = a; 
                a = b; 
                b = temp; 
        } 
}

위에서도 지적했듯, 자바는 모든 값넘김을 value로 하기 때문에
이 코드는 우리가 생각했던 대로 동작하지 않을 겁니다.

결과

before swap...
a is 10
b is 50
after swap...
a is 10
b is 50

[출처] Pass by Value|작성자 무릉

+ Recent posts