기본형 매개변수와 참조형 매개변수 메서드의 매개변수를 기본형으로 선언하면
단순히 저장된 값만 얻지만, 참조형으로 선언하면 값이 저장된 곳의 주소를 알 수 있기 때문에
값을 읽어 오는 것은 물론 값을 변경하는 것도 가능하다.
- 기본 매개변수 : 변수의 값을 읽기만 할 수 있다.
- 참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다.
class Data {
int x;
}
class aaa {
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메서드에서 main메서드로 부터 넘겨 받은 d.x의 값을 1000으로 변경 했는데도,
main메서드에서는 d.x의 값이 그대로이다.
즉, change() 메서드안에 들어갈 값은 d.x 라서 객체 주소값이 아니라,
단순한 '3', '5', "spring", "sky" 같은 값이기 때문에 원본(d) 가 아닌 복사본(주소가 아닌 값들)이라고
말하는 것이다. 그렇기에 change() 메서드를 들렸다 다시 메인메서드로 와도 change메서드 들어가기 전 값이 출력 되는 것이다.
이전 예제와 달리 d.x의 값이 변경 되었다.
change메서드의 매개변수가 참조형이라서 값이 아니라 ‘값이 저장된 주소’를 change 메서드에게
넘겨주었기 때문에 값을 읽어오는 것뿐만 아니라 변경하는 것도 가능하다.
change메서드의 매개변수를 참조형으로 선언했기 때문에, x의 값이 아닌 주소가 매개변수
d에 복사 되었다. 그러면 main메서드의 참조변수 d와 change메서드의 참조변수 d는 같은 객체를 가리키게 된다. 그래서 매개변수 d로 x의 값을 읽는 것과 변경하는 것이 모두 가능한 것이다.
class Data {
int x;
}
class aaa {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d);
System.out.println("After change(d)");
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)
main() : x = 1000
배열도 객체와 같이 참조변수를 통해 데이터가 저장된 공간에 접근한다는 것을 이미 배웠다.
Date클래스 타입의 참조변수 d와 같이 변수 x도 int배열타입의 참조변수이기 때문에 같은 결과를 얻는다.
매개변수의 타입이 배열이니까, 참조형 매개변수이다. sortArr메서드에서 정렬한 것이 원래의 배열에 영향을 미친다.
이 예제는 반환값이 있는 메서드를 반환값이 없는 메서드로 바꾸는 방법이다.
참조형 매개변수를 활용하면 반환값이 없어도 메서드의 실행결과를 얻어 올 수 있다.
밑에 코드 처럼 말이다.
void로 선언해주고, 배열을 통해 빈 배열에 값을 넣어서 main에서 까지 저장 시키는 방법이다.
class aaa {
int add(int a, int b) {
return a + b;
}
void add(int a, int b, int[] result) {
result[0] = a + b; // 매개변수로 넘겨받은 배열에 연산결과를 저장
}
public static void main(String[] args) {
aaa r = new aaa();
int result = r.add(3, 5); // r은 aaa 클래스 안에 있는 add()메서드에 접근하기 위해 사용한 것이다.
System.out.println(result);
int[] result2 = {0}; // 배열을 생성하고 result2[0]의 값을 0으로 초기화
r.add(3, 5, result2);
System.out.println(result2[0]);
}
}
매개변수뿐만 아니라 반환타입도 참조형이 될 수 있다.
반환타입이 참조형이라는 것은 반환하는 값의 타입이 참조형이라는 얘긴데,
모든 참조형 타입의 값은 ‘객체의 주소’ 이므로 그저 정수값이 반환되는 것일 뿐이다.
copy메서드는 새로운 객체를 생성한 다음에, 매개변수로 넘겨받은 객체에 저장된 값을
복사해서 반환한다. 반환하는 값이 Date객체의 주소이므로 반환 타입이 ‘Data’ 인것이다.
반환타입이 ‘참조형’이라는 것은 메서드가 ‘객체의 주소’를 반환한다는 것을 의미한다.
class Data {
int x;
}
class aaa {
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를 생성한다.
tmp.x = d.x; // d.x의 값을 tmp.x에 복사한다.
return tmp; // 복사한 객체의 주소를 반환한다.
}
}
Reference
남궁 성 지음, 『자바의 정석』, 도우출판.