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 자체를 변경 할 순 없다. (다른 주소값으로 변경할 수 없다)
'Java > 기본' 카테고리의 다른 글
[java] try catch with resources Exception 예외처리 (0) | 2019.10.03 |
---|---|
[java] split() example (자바 스플릿 함수 예제, 문자열 잘라서 배열로 만들기) (0) | 2019.10.01 |
java substring, lastindex, replace 사용법 (문자열자르기,확장자명 가져오기) (0) | 2019.09.30 |
java hashmap use sample , change value (자바 해쉬맵 사용법 , 값value 변경하기) (0) | 2019.09.29 |
java 환경변수 설정 (윈도우 10) (2) | 2019.09.26 |
최근댓글