자바에서는 메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨준다. 메서드의 매개변수를 기본형으로 선언하면 단순히 저장된 값만 얻지만, 참조형으로 선언하면 값이 저장된 곳의 주소를 알 수 있기 때문에 값을 읽어 오는 것은 물론 값을 변경하는 것도 가능하다.
기본형 매개변수 : 변수의 값을 읽기만 할 수 있다. (read only)
참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다. (read & write)
class Data { int x; }
class PrimitiveParamEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d.x);
System.out.println("After change(d.x)");
System.out.println("main() : x = " + d.x);
}
static void change(int x) { // 기본형 매개변수
x = 1000;
System.out.println("change() : x = " + x);
}
}
실행결과
main() : x = 10
change() : x = 1000
After change(d.x)
main() : x = 10
위의 코드에서 기본형 매개변수를 받아 호출하는 change를 보면 기본형 매개변수 int x를 썼다. 이때 int x는 change 메서드에서 1000으로 바뀌었음에도 d.x는 10으로 나온다.
그 이유는 'd.x'의 값이 변경된 것이 아니라, change메서듸 매개변수 x의 값이 변경된 것이기 때문에 원본에는 아무런 영향을 미치지 못한다.
기본형 매개변수는 변수에 저장된 값만 읽을 수만 있을 뿐 변경할 수 없기 때문에 d.x의 값에는 변화가 없다.
class Data { int x; }
class ReferenceParamEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d.x);
System.out.println("After change(d.x)");
System.out.println("main() : x = " + d.x);
}
static void change(Data d) { // 기본형 매개변수
d.x = 1000;
System.out.println("change() : x = " + d.x);
}
}
실행결과
main() : x = 10
change() : x = 1000
After change(d.x)
main() : x = 1000
기본형 매개변수의 코드와는 달리 change 메서드를 호출한 후에 d.x의 값이 변경되었다. change메서드의 매개변수가 참조형이기 때문에 '값이 저장된 주소'를 change 메서드에게 넘겨주었기 때문에 값을 읽어오는 것뿐만이 아닌 변경하는 것도 가능하기 위와 같은 결과가 나왔다.
참조형 매개변수는 값이 저장된 주소를 사용하기 때문에 변수의 값을 읽거나 변경할 수 있다.
매개변수뿐만 아니라 반환타입도 참조형이 될 수 있다.
모든 참조형 타입의 값은 '객체의 주소'이므로 그저 정수값이 반환되는 것일 뿐 특별할 것이 없다.
class Data { int x; }
class ReferenceReturnEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
Data d2 = copy(d);
System.out.println("d.x =" + d.x);
System.out.println("d2.x =" + d2.x);
}
static Data copy(Data d){
Data tmp = new Data();
tmp.x = d.x;
return tmp;
}
}
실행결과
d.x = 10
d2.x = 10
위의 코드에서 주의깊게 봐야할 것은 copy메서드이다.
static Data copy(Data d){
Data tmp = new Data(); // 새로운 객체 tmp를 생성
tmp.x = d.x; // d.x의 값을 tmp.x에 복사
return tmp; // 복사한 객체의 주소를 반환
}
copy메서드의 반환타입은 'Data'이며, 호출결과를 저장하는 변수의 타입 역시 'Data'타입의 참조변수이다.
위의 copy메서드는 반환값 tmp를 가지며, tmp는 d.x의 값을 복사했다. copy메서드가 복사한 객체의 주소 d.x를 가진 tmp를 d2.x로 반환했기 때문에 실행결과에서 d2.x가 10이 나온것이다.
"반환타입이 '참조형'이라는 것은 메서드가 '객체의 주소'를 반환한다는 것을 의미한다."
참조 자바의 정석 p264 ~ p269