on
자바의 정석2-4 기본형 매개변수와 참조형 매개변수
자바의 정석2-4 기본형 매개변수와 참조형 매개변수
기본형 매개변수(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
https://blog.naver.com/rudals6817/222505619081
from http://everysmallstep.tistory.com/71 by ccl(A) rewrite - 2021-12-31 12:28:09