주소에 의한 참조는 무슨 말일까요? 메모리에 어떤 값을 저장했다면 그 값이 담긴 방(room)과 그 방을 가리키는 주소가 있습니다. Call-by-reference는 주소를 참조(reference)해서 값들을 조작합니다. 메소드 간 통신(값이나 주소를 주고받는 행위)을 한다고 할 때 주소만 넘겨서 서로 주소를 공유하고 값들을 공유해서 조작하는 방법을 뜻합니다. C 언어에서 다루는 포인터(Pointer)에서 연장된 개념이라고 볼 수 있겠네요.
이에 대비되는 개념으로 Call-by-value가 있습니다. 그 방에 들어가 바로 값(value)을 꺼내오고 값 자체를 넘겨버립니다. 이 과정에서 메모리 주소는 절대 알려주지 않습니다. 그러므로 메소드 간 통신시 전달하거나 받은 값은 각각 메소드가 알아서 조작하고 그 값이 바뀐 결과가 공유되거나 하지 않습니다.
포켓몬 고를 비유로 들면(실제로 해본적은 없어요) 이웃이 피카츄가 동네 체육관에 나타났다고 해서 나도 좀 알려달라고 부탁하는 상황이라면 Call-by-refence 방식은 그 체육관의 주소를 알려주는 것이고, Call-by-value 방식은 체육관을 통째로 복제한 다음 눈 앞에 던져주는 거랑 똑같다고 보면 되겠습니다.
다음 예제를 보면 그냥 Shop과 BeginnerShop이 있는데, shop은 reference 호출을 하며, BeginnerShop은 value 호출을 합니다. 결과를 보면 차이를 알 수 있을 것입니다.
import java.util.Scanner;
public class CallByReference {
static Scanner s = new Scanner(System.in);
public static void main(String[] args) {
// 주인공의 정보는 메인 프로그램에 만드는것이 적합함
/* int lv = 1;
int gold = 1000;
int att = 100;
int def = 50;*/
// 이 정보들을 메소드간에 어떻게 공유할것인가?
// gold의 주소를 넘기면 된다.
// 0:레벨, 1:골드, 2:공격, 3:방어
int[] playerInfo = {1, 1000, 100, 50};
System.out.println("바람의 나라 게임에 접속한 것을 환영합니다.");
System.out.println("마을");
System.out.println("어디?");
System.out.print("1. 남쪽(상점-베테랑) / 2. 동쪽(상점-초보) ... >> ");
int menu = s.nextInt();
switch(menu) {
case 1:
shop(playerInfo);
break;
case 2:
beginnerShop(playerInfo[0], playerInfo[1], playerInfo[2], playerInfo[3]);
}
System.out.println("\n상점 이용 후 남은 돈: " + playerInfo[1]);
}
// Call-by-value로 값을 넘겨줬다면 상점에 다시 접속하면 모든 정보가 초기 정보로 리셋되어 있을것
// Call-by-reference로 주소를 넘겨줬으므로 아이템 구입에 따라 다시 접속해도 리셋되지 않음
public static void shop(int[] playerInfo)
{
while(true)
{
System.out.println("\n상점, 무엇?");
System.out.println("1. 포션(100G)");
System.out.println("2. 검(500G)");
System.out.println("....");
System.out.print("입력: ");
int menu = s.nextInt();
if(menu == 1)
{
playerInfo[1] -= 100;
System.out.println("\n포션 구입");
System.out.println("남은 돈: " + playerInfo[1]);
}
else if(menu == 2)
{
playerInfo[1] -= 500;
System.out.println("\n검 구입");
System.out.println("남은 돈: " + playerInfo[1]);
}
else
break;
}
System.out.println("\n상점을 빠져나왔다. ");
}
public static void beginnerShop(int level, int gold, int att, int def)
{
while(true)
{
System.out.println("\n상점입니다, 무엇을 구매하시겠습니까?");
System.out.println("1. 포션(100G)");
System.out.println("2. 검(500G)");
System.out.println("....");
System.out.print("입력: ");
int menu = s.nextInt();
if(menu == 1)
{
gold -= 100;
System.out.println("\n포션 구입");
System.out.println("남은 돈: " + gold);
}
else if(menu == 2)
{
gold -= 500;
System.out.println("\n검 구입");
System.out.println("남은 돈: " + gold);
}
else
break;
}
System.out.println("\n이용해주셔서 감사합니다. ");
}
}
일반 상점(call-by-reference)
(......) 상점, 무엇? 1. 포션(100G) 2. 검(500G) .... 입력: 2 검 구입 남은 돈: 400 상점, 무엇? 1. 포션(100G) 2. 검(500G) .... 입력: 3 상점을 빠져나왔다. 상점 이용 후 남은 돈: 400
초보 상점(call-by-value)
상점입니다, 무엇을 구매하시겠습니까? 1. 포션(100G) 2. 검(500G) .... 입력: 2 검 구입 남은 돈: 400 상점입니다, 무엇을 구매하시겠습니까? 1. 포션(100G) 2. 검(500G) .... 입력: 0 이용해주셔서 감사합니다. 상점 이용 후 남은 돈: 1000





0개의 댓글