JAVA

값 전달 방식에 따른 차이 (Pass by)

태로미 2023. 3. 12. 22:11

 

 

 

 

 

 

 

 

 

 

📍    값 전달 방식에 따른 차이 (Pass by)

–   메서드 호출 시 값 전달 방식에 따른 차이.
–   메서드 파라미터로 기본 데이터타입과 참조 데이터타입 전달 시 차이.
     →   메서드를 호출하여 값을 전달할 경우,  값의 복사가 일어남.

 

 

 

1.   Pass by value (값에 의한 전달)

–   메서드 호출 시,  기본 데이터타입 데이터 전달하는 경우
     →   실제 값(실제 데이터)을 복사해서 전달.
–   호출된 메서드 내에서 전달받은 값(복사한 데이터)을 변경해도 원본 데이터는 아무런 이상이 없음.
     ex )   도서관에서 ebook으로 책을 빌림.  형광팬 그어도 복사본이므로 다른사람이 빌렸을 때 형광팬 표시가 없음.

 

 

 

2.   Pass by reference (참조에 의한 전달)

–   메서드 호출 시 참조 데이터타입 데이터 전달하는 경우,
      →   실제 값이 있는 공간의 주소 값(참조 값)을 복사해서 전달.
–   호출된 메서드 내에서 전달받은 값(복사한 주소값)을 언급하여 해당 주소에 있는 데이터를 변경하는 경우,
     원본 데이터도 동일한 주소값을 참조하므로 변경된 결과에 영향을 받음.   
      ex )   도서관에서 내가 빌리고 싶은 책이 있는 주소를 알려줘서 내가 찾아가서 책을 빌림. 
               이제는 책에 형광팬을 그으면 다른사람이 그 책을 빌렸을 때 형광팬이 그어져있는 책을 빌리게 됨.


EX   )

 

•   클래스 생성

// PassByTest 클래스
class PassByTest{
	// 기본타입 데이터 전달
	public void changePrimitiveType(int money) {
		money -= 5000;
		System.out.println("changePrimitiveType() 메서드의 money = " + money);
	}
    
    	// 참조타입 데이터 전달
	public void changeReferenceType(Money m) {
		m.money -= 5000;
		System.out.println("changeReferenceType() 메서드의 money = " + m.money);
	}
}


// Money 클래스
class Money{
	int money = 10000;
}

–   changePrimitiveTyipe() 메서드는  기본타입 데이터(실제 값 = 리터럴)를 전달 받음 → 복사
     →   파라미터로 전달 받은 기본타입인 변수 money의 데이터를 변경함.

     →   10000에서 -5000하여 5000을 남게함.

–   changeReferenceType() 메서드는 참조타입 데이터(주소 값 = 참조 값) 전달 받음 → 복사

     →   파라미터부분에 참조타입 데이터가 전달되어 Money클래스의 주소를 가지고 있는 변수 m이 파라미터에 들어감.

            ex )   int a 는 데이터타입 + 변수명,  Money m 또한 데이터타입(클래스) + 변수명

     →   전달받은 주소 값에 해당하는 인스턴스에 접근하여,  인스턴스 내의 멤버변수(실제 값)을 변경함.

     →   10000에서 -5000하여 5000을 남게함.

 

 

•   인스턴스 생성  & 메서드 호출

 

1.   메서드 파라미터로 기본 데이터타입 변수 값을 전달할 경우

// 인스턴스 생성
Money m = new Money();
PassByTest pbt = new PassByTest();
		
System.out.println("changePrimitiveType() 메서드 호출 전 money = " + m.money);	// 10000
		
pbt.changePrimitiveType(m.money);
// money 인스턴스에 저장된 값(10000)이 복사됨
		
System.out.println("changePrimitiveType() 메서드 호출 후 money = " + m.money);	// 10000

–   changePrimitiveType() 메서드를 호출하기 전,  Money에는 '10000' 데이터가 있음.

–   Money 클래스의 멤버변수에 접근하기 위해 참조변수명.멤버변수명으로 메서드의 파라미터에 '10000' 데이터를 전달.

     →    이 때,  메서드의 파라미터는 기본타입(int)이므로 실제 값을 복사해서 전달하는 것.

     →    메서드를 실행하였으므로 -5000이 되어 결과는 5000이 출력됨.

–   그러나 Monye 클래스의 멤버변수 money(= money 인스턴스)에 접근하여 해당 데이터를 출력해보면

     원본 그대로 10000이 출력됨.

     →    호출된 메서드에서 전달받은 데이터(복사한 실제 데이터)를 변경하더라도,
             원본 데이터에는 아무런 영향이 없음. (=10000원이 그대로 존재함)

   실행 결과

더보기

changePrimitiveType() 메서드 호출 전 money = 10000
changePrimitiveType() 메서드의 money = 5000
changePrimitiveType() 메서드 호출 후 money = 10000

 

 

2.    메서드 파라미터로 참조 데이터타입 변수 값을 전달할 경우

System.out.println("chageReferenceType() 메서드 호출 전 money = " + m.money);	// 10000
		
pbt.changeReferenceType(m);
		
System.out.println("chageReferenceType() 메서드 호출 후 money = " + m.money);	// 5000

–   Money클래스의 인스턴스 주소가 저장된 참조변수 값을 메서드에 전달.
     →   이 때,  메서드의 파라미터는 참조 데이터타입(Money)이므로 주소 값을 복사해서 전달함.

–   호출된 메서드에서 전달받은(복사된) 주소값에 접근하여 인스턴스 내의 데이터를 변경하는 경우,
     원본 데이터도 동일한 주소값을 참조하게 되므로 변경된 값은 원본 데이터에도 영향을 주게 됨.
     →   즉,  동일한 주소값을 참조하므로 어느 한 쪽에서 객체 데이터를 변경하는 경우

           같은 주소값을 참조하는 모두가 '영향을 받음.'
   실행 결과

더보기

chageReferenceType() 메서드 호출 전 money = 10000
changeReferenceType() 메서드의 money = 5000
chageReferenceType() 메서드 호출 후 money = 5000