오늘은 역대급 늦장 부린 날...
다음 주 부터 본 과정 시작!!
정신 똑바로 차리고, 나의 부족을 인지한 만큼 그보다 더 열심히 하자.
시작에 앞서 매개변수가 뭘까?
💻 매개변수
매개변수(parameter)와 인수(arguments)
매개변수는 메소드에 입력으로 전달된 값을 받는 변수를 의미하고,
인수는 메소드를 호출할 때 전달하는 입력값을 의미한다.
기본형 매개변수 - 변수의 값을 읽기만 할 수 있다.(read only)
참조형 매개변수 - 변수의 값을 읽고 변경할 수 있다.(read & write)
기본형 매개변수
Class Data { int x; }
class Ex6_6 {
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 메서드가 Stack영역에 쌓임.
- Data의 객체 x 가 생성 → x 는 0 으로 초기화
- d 는 참조 타입 변수로 x 의 번지수를 저장함.
- d.x = 10 → 참조 타입 d 의 x 값을 찾아가서 10으로 변경 ( x, 0 → 10 )
- change(d.x) → d.x 는 10, 10을 인자로써 change 메서드로 보냄.
- change 메서드가 Stack 영역에 main 메서드 위에 쌓임.
- change 메서드는 매개변수를 기본 타입으로 받음.
- change 메서드가 로컬 변수(Local varialble)로 x를 가짐.
- 2의 x와 7의 x는 이름만 같을 뿐, 다른 변수이다.
- change 메서드의 지역 변수 x는 10 → 1000으로 바뀐다.
- change 메서드가 Stack 영역에서 정리됨.
- main 메서드가 마저 실행되고, Stack 영역에서 정리되면서 프로그램이 종료됨.
// 결과 값
main() : x = 10
change() : x = 1000
After change(d.x)
main() : x = 10
참조형 매개변수
class Data2 { int x; }
class Ex6_7 {
public static void main(String[] args) {
Data2 d = new Data2();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d);
System.out.println("After changer(d)");
System.out.println("main() : x = " + d.x);
}
static void change(Data2 d) { // 참조형 매개변수
d.x = 1000;
System.out.println("change() : x = " + d.x);
}
}
- main 메서드가 Stack에 쌓임.
- Date2의 객체 x가 생성 → x 는 0으로 초기화.
- 참조 타입 변수 d 에는 x 를 가리키는 번지수가 저장.
- d.x → d 가 가리키는 x 의 값을 10으로 바꿈. (x, 0 → 10)
- change(d) 메서드가 Stack의 main 메서드 위에 쌓임.
- change 메서드는 매개변수를 참조 타입으로 받는다.
- change 메서드는 d를 받고, d 에는 객체를 가리키는 번지수가 저장되어 있다.
- change 메서드에서 d.x 는 d 에 저장된 번지수를 통해 가리키는 x 의 값을 1000으로 변경 시킨다.
- change 메서드가 종료되면 스택에서 정리되며,
- 이미 객체 자체의 값이 변경되었기 때문에 남아 있는 것은 메인 메서드와 Data2 객체 안의 변수 x = 1000이라는 값이다.
// 결과 값
main() : x = 10
change() : x = 1000
After change(d)
main() : x = 1000
참조형 매개변수를 사용하면...
객체를 가리키는 주소 값을 받아 올 수 있다. 즉 직접적으로 해당 객체에 접근할 수 있다!!
참조형 반환타입
Class Data { int x; }
class Ex_8 {
public static void main(String[] args) {
Data3 d = new Data3();
d.x = 10;
Data3 d2 = copy(d);
System.out.println("d,x = " + d.x);
System.out.println("d2.x = " + d.x);
}
Static Data3 copy(Data3 d) {
Data3 tmp = new Data3(); // 새로운 변수 tmp를 생성한다.
tmp.x = d.x; // d.x의 값을 tmp.x에 복사한다.
return tmp; // 복사한 객체의 주소를 반환한다.
}
}
- main 메서드가 호출되면서 Stack 에 쌓임.
- Data3의 객체 x가 생성 → x 는 기본값인 0으로 초기화.
- d 는 x 를 가리키는 번지값를 저장한며, d.x 를 통해 객체 x에 접근해 값을 10으로 변경.
- 참초 타입 변수 d2가 만들어진다. ( 변수에 주소값은 할당받지 못한 상태)
- d2가 만들어 진 후, copy 메서드를 호출하면서 Stack 에 쌓음. → main 메서드는 대기 상태로 전환
- copy 메서드 위에 참조 타입 변수 d가 만들어진다. ≠ main 메서드의 d 와는 이름은 같지만 다른 변수.
- 변수 tmp 가 선언되고, Data3의 객체 x 가 생성되며 기본값인 0으로 초기화 된다.
- tmp.x = d.x; d.x 의 값 10을 tmp가 가리키는 x 에 복사한다. ( d.x 와 tmp.x 가 가지는 번지값은 다르다. )
- 그리고 객체의 번지값이 담긴 tmp를 반환한다.
- 할 일을 다 마무리한 copy 메서드는 스택에서 정리되며,
- 메인 메소드가 대기 상태에서 실행상태로 전환된다.
- copy 메서드는 정리되었지만, copy 메서드가 생성해 둔 객체는 main 메서드에서 사용되므로 정리되지 않는다.
- 결과적으로 d.x 와 d2.x 둘 다 값은 10을 가지지만, 서로 다른 객체에 담겨있다.
( d == d2 → false, 서로 다른 번지값을 가지고 있으므로)
<참고자료>
[Java] Java는 Call by reference가 없다
Call by Value와 Call By Reference가 뭘까? 프로그래밍을 하다 보면 꼭 알고 넘어가야 하는 개념이 있습니다. 바로 Call By Value, Reference입니다. 어떤 언어를 공부하든 나오는 개념이기도 합니다. Call by value
deveric.tistory.com