주소에 의한 참조는 무슨 말일까요? 메모리에 어떤 값을 저장했다면 그 값이 담긴 방(room)과 그 방을 가리키는 주소가 있습니다. Call-by-reference는 주소를 참조(reference)해서 값들을 조작합니다. 메소드 간 통신(값이나 주소를 주고받는 행위)을 한다고 할 때 주소만 넘겨서 서로 주소를 공유하고 값들을 공유해서 조작하는 방법을 뜻합니다. C 언어에서 다루는 포인터(Pointer)에서 연장된 개념이라고 볼 수 있겠네요.

이에 대비되는 개념으로 Call-by-value가 있습니다.  그 방에 들어가 바로 (value)을 꺼내오고 값 자체를 넘겨버립니다. 이 과정에서 메모리 주소는 절대 알려주지 않습니다. 그러므로 메소드 간 통신시 전달하거나 받은 값은 각각 메소드가 알아서 조작하고 그 값이 바뀐 결과가 공유되거나 하지 않습니다.

포켓몬 고를 비유로 들면(실제로 해본적은 없어요) 이웃이 피카츄가 동네 체육관에 나타났다고 해서 나도 좀 알려달라고 부탁하는 상황이라면 Call-by-refence 방식은 그 체육관의 주소를 알려주는 것이고, Call-by-value 방식은 체육관을 통째로 복제한 다음 눈 앞에 던져주는 거랑 똑같다고 보면 되겠습니다.

다음 예제를 보면 그냥 ShopBeginnerShop이 있는데, shopreference 호출을 하며, BeginnerShopvalue 호출을 합니다. 결과를 보면 차이를 알 수 있을 것입니다.

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