테스트 없이 눈으로만 코딩할 때 가장 쉬운 부분이 call by value 와 call by refence 를 이해하지 못할 때 생기는 오류가 아닐까 싶다.
기본형과 객체가 기본형은 call by value 이고 객체는 call by refence 라는 대부분의 java 개발자들이 알고 있을꺼라 생각한다.
그 예로 swap 가장 많이 설명하는데..
예제 1)
class Test {
private static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
public static void main(String args[]) {
int a = 1;
int b = 2;
System.out.println("a => " + a);
System.out.println("b => " + b);
swap(a, b);
System.out.println("------- swap 후 -------");
System.out.println("a => " + a);
System.out.println("b => " + b);
}
}
예제 1 의
원하던 결과가 아닌 것을 바로 알아 낼 수 있을 것이다.
메소드에 넘기는 것은 reference 가 아닌 value 이기 때문에...
쉽다.
다음 예제 2 를 보자
예제 2)
class Test {
private static void swap(Integer a, Integer b) {
Integer temp = a;
a = b;
b = temp;
}
public static void main(String args[]) {
Integer a = new Integer(1);
Integer b = new Integer(2);
System.out.println("a => " + a.intValue());
System.out.println("b => " + b.intValue());
swap(a, b);
System.out.println("------- swap 후 -------");
System.out.println("a => " + a.intValue());
System.out.println("b => " + b.intValue());
}
}
예제 2
경우 Integer 는 Object 이다. Object 는 call by reference
따라서 위의 예제는 원하는 결과를 가져올 것이다.
그러나 실행을 하면 예제 1과 전혀 다르지 않다는 것을 알
있다.
왜? 객체는 call by reference 라며 사기친거야?
말하면 객체는 call by reference 맞다
그러나 해당 객체를
새로운 reference 를 참조해서 넘기는 것이다.
따라서 동일한 객체를
있지만
main 에서의 reference 값과 swap 함수에서의 reference 값은
따라서 위의 예제의 경우 원하는 결과가 나오지 않는다.
이부분이 가장 이해가 힘들었는데, 즉 메소드에서 변수의 주소를 받았다 하더라도 실제 메소드 안에서 실행될때는 지역변수일 뿐입니다. 즉, 메소드를 벗어나게 되면 영향력이 없어지는 것이죠..
그래서 영향력이 있을때인 메소드 안에서 직접 그 주소의 값을 변경하면 영향을 받지만, 그런것이 아닌 단순한 주소의 복사는, 그 메소드 안에있는 지역변수의 변화일 뿐 실제 값에는 영향이 없습니다.
|
어떻게 해야 해?
예제 3 을 보자.
예제 3)
class Test {
int value;
Test(int value) {
this.value = value;
}
private static void swap(Test a, Test b) {
int temp = a.value;
a.value = b.value;
b.value = temp;
}
public static void main(String args[]) {
Test a = new Test(1);
Test b = new Test(2);
System.out.println("a => " + a.value);
System.out.println("b => " + b.value);
swap(a, b);
System.out.println("------- swap 후 -------");
System.out.println("a => " + a.value);
System.out.println("b => " + b.value);
}
}
예제 2와 같이 객체의 reference 를 넘긴다.
reference 를 직접
게 아니라.
reference 가 참조하는 객체의 value 를 변경하고 있다.
같은 객체를 보고 있는 main 에서도 값이 바뀌는 것을 알
있다.
call by reference
해당 객체의 주소값을 직접 넘기는 게 아닌 객체를 보는 또 다른 주소값을 만들어서 넘기다는 사실을 잊지 말자~