본문 바로가기
멀티캠퍼스 풀스택 과정/Java의 정석

자바의 정석2-4 기본형 매개변수와 참조형 매개변수

by 이쟝 2021. 12. 31.

기본형 매개변수(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