JAVA call by value or call by reference??

 

결론적으로 java의 경우 call by value로 보면 될 것 같습니다.

 

자세한 내용은 아래 예시를 통해 설명하겠습니다.

 

call by value : 값에 의한 호출 , 어떤 메소드를 호출 할때 값(데이터) 자체를 파라미터로 던져 로직이 처리되는 호출 방법

                   원본값은 변경되지 않는다.

call by reference : 참조에 의한 호출, 어떤 메소드를 호출 할 때 참조값(주소값)을 파라미터로 던져 로직이 처리되는 호

                        출 방법, 메소드 내에서 파라미터를 변경할 경우 파라미터가 존재하는 위치의 주소값에 대한 변경이

                        이뤄지므로,  원본값이 변경된다.

 

먼저 call by value 샘플을 보겠습니다.

아래 처럼 변수에 대한 값을 초기화 하고, 메소드 내에서 값을 변경하는 로직을 추가해줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.supercoding;
 
public class Main {
 
    public static void main(String[] args) {
        int x = 10;
        int y = 20;
        System.out.println("출력 x : " + x);
        System.out.println("출력 y : " + y);
 
        //call by value 테스트
        callbyValueTest(x,y);
        System.out.println("출력 x : " + x);
        System.out.println("출력 y : " + y);
    }
 
    public static void callbyValueTest(int x, int y){
        int temp = 0;
        temp = x;
        x = y;
        y = temp;
    }
 
}
 

위 코드의 결과값 : 

출력 x : 10 
출력 y : 20 

---------callbyValueTest(x,y)  호출 -------------
출력 x : 10 
출력 y : 20

 

값이 변경되지 않았음 (call by value 확인)

 

 

아래는 call by reference 테스트 샘플이다. java에서 특이한 점은 object를 파라미터로 던질 때 발생한다.

앞선 예제에서는 int 타입, 즉 primitive type의 변수를 파라미터로 던졌지만,

아래 예시 코드는 객체를 파라미터로 던져 메소드를 호출한다.

 

[메소드 간단설명]

changeName() 메소드는 객체의 속성값을 변경하는 로직을 처리한다.

changeObject() 메소드는 파라미터의 객체 변수에 다른 객체를 복사하는 로직을 처리한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.supercoding;
 
public class Main {
 
    public static void main(String[] args) {
 
        Car c = new Car("벤츠",100);
        System.out.println("차 이름 : "+ c.getName());
        System.out.println("가격 : " +c.getPrice());
 
        changeName(c);
        System.out.println("------------------------changeName() 호출 --------------------------");
        System.out.println("차 이름 : "+ c.getName());
        System.out.println("가격 : " +c.getPrice());
 
        System.out.println("------------------------changeObject() 호출 --------------------------");
       changeObject(c);
        System.out.println("차 이름 : "+ c.getName());
        System.out.println("가격 : " +c.getPrice());
 
    }
 
    public static void changeName(Car cr){
       cr.setName("아우디");
    }
 
    public static void changeObject(Car cr){
        Car tempc = new Car("소나타",100);
       cr = tempc;
 
        System.out.println("변경 차 이름 : "+ cr.getName());
        System.out.println("변경 가격 : " +cr.getPrice());
 
    }
 
}
 
class Car {
    private String name;
    private int price;
 
    Car(String name, int price) {
        this.name = name;
        this.price = price;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getPrice() {
        return price;
    }
 
    public void setPrice(int price) {
        this.price = price;
    }
}
 
 

위 소스 결과값 : 

차 이름 : 벤츠
가격 : 100
------------------------changeName() 호출 --------------------------
차 이름 : 아우디
가격 : 100

------------------------changeObject() 호출 -------------------------- 

변경 차 이름 : 소나타
변경 가격 : 100
차 이름 : 아우디
가격 : 100

 

잘 보면 객체를 파라미터로 던진 후 던진 파라미터 객체의 속성값을 변경하면 메소드 밖에서도 객체의 속성 변경내역이 적용된다.

changeName(Car cr) 메소드에서 전달 받는 객체는 즉각적으로 메소드 내에서 cr 변수에 복사된다.(c = cr)

이제, c와 cr 객체는 같은 주소값을 바라보게 된다. 

 

이러면 call by reference처럼 보인다. 하지만, 같은 주소값을 바라보긴 하지만 c , cr은 다른 객체이다. (cr은 복사본임)

 

changeObject() 메소드는 java가 완벽한 call by reference 언어는 아니란것을 확인해준다. 

메소드내에서 생성한 Car 객체를 파라미터 변수에 입력해준다. call by reference라면, 새로 생성한 객체의 값이 저장되어야한다. (메소드 내에서 출력한 내용처럼 변경 차 이름 : 소나타 )

 

하지만, 메소드 밖에서 확인을 해보면 원본 객체는 변경되지 않았다.(call by reference 아님)

[정리]

*java에서 primitive type 변수는 call by value로 전달한다.

 object를 파라미터로 던질 경우 object의 속성값은 메소드 내에서 변경가능하지만. object 자체를 변경 할 순 없다. (다른 주소값으로 변경할 수 없다)

 

LIST
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기