값 전달 방식에 따른 차이 (Pass by)
📍 값 전달 방식에 따른 차이 (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