기본형 매개변수(Primitive parameter)와 참조형 매개변수(Reference parameter)
기본형 매개변수(8개) – 변수의 값을 읽기만 할 수 있다.(read only)
참조형 매개변수 – 변수의 값을 읽고 변경할 수 있다.(read & write)
메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨주게 되는데 이때 매개변수 타입이 무엇인가에 따라 결과가 다르게 나타남
1) 기본형 매개변수
- 메서드에서 지역변수의 값이 복사되는 값(지역변수는 메서드를 벗어나면 그 값도 소멸됨)
- 기본형 매개변수는 실질 값이 복사되는 것이고, 실질값이 복사되어 소멸하면 그 해당 복사된 변수의 값은 소멸됨
<예제와 출력값>
maix(): x = 10
change(): x = 1000
After change(d.x)
main(): x = 10
public class PrimitiveParaEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("maix(): 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);
}
}
class Data { int x; }
1) public static void main | main 메서드 실행(스택에 올라가 있는 상태) 프로그램 시작 |
2) Data d = new Data( ); | 참조변수 d가 생성되고 , Data 클래스의 객체 생성 |
3) d.x = 10; | 참조변수 d가 가리키는 인스턴스(객체) x에 값 안에 10 할당(초기화) |
4) System.out.println("maix(): x = " + d.x); |
println 메서드가 실행되면서 10 출력 (d가 가리키는 x객체에는 10이 할당되어 있어서) |
5) change(d.x); | change 메서드 실행 |
6) static void change(int x) { | change 메서드가 호출되면서 d.x가 change 메서드의 매개변수 x에 복사됨(값 10이 복사됨) |
7) x = 1000; System.out.println("change(): x = "+x); | 매개변수(지역변수) x에 1000을 할당하게 되면 println 메서드가 실행되면서 x는 1000이 출력 |
8) change 메서드가 종료되면서 매개변수(지역변수) x는 change메서드와 함께 스택에서 제거됨! |
|
9) System.out.println("After change(d.x)"); System.out.println("main(): x = " + d.x); |
main 메서드로 다시 돌아가게 되고, println 메서드를 호출해서 d.x는 10으로 출력! |
-> change메서드에서 main메서드로 넘겨받은 d.x의 값은 1000으로 변경됐지만 main메서드의 d.x의 값이 변경된 게 아니라 복사된 change 메서드의 매개변수 x의 값이 변경된 것
(기본형 매개변수는 저장된 값만 읽을 수 있을 뿐 변경할 수 없음)
기본형 매개변수(8개) – 변수의 값을 읽기만 할 수 있다.(read only)
참조형 매개변수 – 변수의 값을 읽고 변경할 수 있다.(read & write)
2) 참조형 매개변수
인스턴스의 주소가 복사되었고, 값을 읽어오는 것은 물론. 값을 변경하는 것도 가능하다.
<예제와 출력값>
maix(): x = 10
change(): x = 1000
After change(d.x)
main(): x = 1000
public class PrimitiveParaEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("maix(): x = " + d.x);
change(d);
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);
}
}
class Data { int x; }
1) public static void main | main 메서드 실행(스택에 올라가 있는 상태) 프로그램 시작 |
2) Data d = new Data( ); | 참조변수 d가 생성되고 , Data 클래스의 객체 생성 |
3) d.x = 10; | 참조변수 d가 가리키는 인스턴스(객체) x에 값 안에 10 할당(초기화) |
4) System.out.println("maix(): x = " + d.x); |
println 메서드가 실행되면서 10 출력 (d가 가리키는 x객체에는 10이 할당되어 있어서) |
5) change(d.x); | change 메서드 실행 |
6) static void change(Data d) { | change 메서드가 호출되면서 참조변수 d의 값(주소)이 매개변수 d에 복사되게 됨 |
7) d.x = 1000; System.out.println("change(): x = "+d.x); | 매개변수 d에 저장된 주소값으로 인스턴스 x에 접근이 가능함. change메서드에서 매개변수 d로 x의 값을 1000을 할당하고 println메서드를 실행되면서 x는 1000 출력 |
8) change 메서드가 종료되면서 매개변수(지역변수) x는 change메서드와 함께 스택에서 제거되지만 change메서드 안에서의 참조변수 d가 기존의 값인 x를 바꿨기 때문에 main 메서드에서의 d.x의 값은 1000으로 바뀌게 됨 |
|
9) System.out.println("After change(d.x)"); System.out.println("main(): x = " + d.x); |
main 메서드로 다시 돌아가게 되고, println 메서드를 호출해서 d.x는 1000으로 변경되었기 때문에 1000으로 출력! |
-> change 메서드의 매개변수를 참조형으로 선언(Data 타입)해서 x의 값이 아닌 주소가 매개변수 d에 복사됨
-> main 메서드의 참조변수 d와 change메서드의 참조변수 d가 같은 객체를 가리키게 되기 때문에 매개변수 d로 x의 값을 읽는 것과 변경하는 것이 모두 가능하게 됨
-> 메서드한테 참조형 매개변수를 통해서 객체의 주소를 전달해줌 객체를 다룰 수 있다
-> 객체를 다룰 수 있다는 것은 주소를 알고 있다는 것이다!! 주소를 알 수 있으면 읽을 수도 있고 쓸 수도 있음 (참조변수 == 주소를 알려주는 리모컨)
3) 참조형 반환타입
-> 참조형 : 객체의 주소를 주고받는 것
<예제와 출력값>
d.x =10
d2.x = 10
public class PrimitiveParaEx {
public static void main(String[] args) {
Data2 d = new Data2();
d.x = 10;
Data2 d2 = copy(d);
System.out.println("d.x =" + d.x);
System.out.println("d2.x = " + d2.x);
}
static Data2 copy(Data2 d) {
Data2 tmp = new Data2();
tmp.x = d.x;
return tmp;
}
}
class Data2 { int x; }
1) public static void main | main 메서드 실행(스택에 올라가 있는 상태) 프로그램 시작 |
2) Data2 d = new Data2( ); | 참조변수 d가 생성되고 , Data2 클래스의 객체 생성 |
3) d.x = 10; | 참조변수 d가 가리키는 인스턴스(객체) x에 값 안에 10 할당(초기화) |
4) Data2 d2 = copy(d); | main 메서드에 참조변수 d2가 먼저 생성되고 copy메서드를 호출! |
5) static Data2 copy(Data2 d) | copy메서드는 참조형 매개변수 Data2 를 통해서 d의 값을 복사한다음 copy 메서드의 지역 참조변수 d를 만듦 |
6) Data2 tmp = new Data2( ); | copy 메서드 tmp라는 새로운 참조변수가 만들어지고 x라는 새로운 객체 생성! |
7) tmp.x = d.x | d.x의 값(객체의 주소)을 tmp.x 값(객체의 주소값)에 복사한다. (tmp.x -> 0x200(10)) |
8) return tmp; | 복사한 객체의 주소(0x200(10))를 main 메서드에 반환하면서 copy메서드는 종료 |
9) Data2 d2 = copy(d); | 다시 main메소드로 돌아와서 d2에 tmp의 값(0x200(10)을 반환 |
10) System.out.println("d.x =" + d.x); System.out.println("d2.x = " + d2.x); |
main메서드가 println 메서드 호출한다.d2.x와 d.x는 같은 값을 가리키고 있어서 똑같이 10이 출력! |
-> 반환 타입이 참조형이라면 객체의 주소를 반환한다는 뜻
-> 메서드의 반환타입(static Data2 copy(Data2 d))과 그 반환값을 넣어줄 참조 변수의 타입(Data2 d2 = copy(d))이 일치해야 한다.
<사진출처>
https://blog.naver.com/hallongjj/222506458377
https://velog.io/@withcolinsong/%EC%B0%B8%EC%A1%B0%ED%98%95-%EB%B0%98%ED%99%98%ED%83%80%EC%9E%85
'멀티캠퍼스 풀스택 과정 > Java의 정석' 카테고리의 다른 글
자바의 정석2-6 오버로딩(overloading) (0) | 2021.12.31 |
---|---|
자바의 정석2-5 static 메서드와 instance 메서드 (0) | 2021.12.31 |
자바의 정석2-3 메서드의 개념(return문, 호출스택) (0) | 2021.12.31 |
자바의 정석2-2 객체의 생성과 사용(cv, iv, lv의 개념) (2) | 2021.12.30 |
자바의정석2-1 객체지향의 개념 (0) | 2021.12.30 |