- 그게 뭐지?
- 프로그래밍을 배우다보면 한번씩은 들어본 Call by value와 Call by reference.. 값을 복사하니, 주소값을 참조하니 어렵게 생각하지말고 직접 경험해보면서 알아보자.
- Call by value
- 우선 자바의 데이터형에 대해 이해해야한다.
- 기본형(primitive type) - Boolean Type(boolean), Numeric Type(short, int, long, float, double, char)
- 참조형(reference type) - Class Type, Interface Type, Array Type, Enum Type, 기본형을 제외한 모든 것들
- 자바에는 메소드의 파라미터값으로 기본형을 받냐, 참조형을 받냐에 따라 같은 코드지만 전혀 다른 결과를 불러온다.
아래의 예제를 보자.
class Updater {
void update(int count) {
count++;
}
}
class Counter {
int count = 0; // 객체변수
}
public class Sample {
public static void main(String[] args) {
Counter myCounter = new Counter();
System.out.println("before update:"+myCounter.count);
Updater myUpdater = new Updater();
myUpdater.update(myCounter.count);
System.out.println("after update:"+myCounter.count);
}
}
Updater 클래스와 Counter 클래스를 모두 메인으로 가져와, count변수를 만들고 해당 변수를 업데이트 시킨 모습이다. 아마도 기존의 카운트가 0에서 1로 늘어나 출력될것 같지만, 실행해보면 다음과 같은 결과를 얻는다.
before update:0
after update:0
왜일까?
메인 메소드를 보면, 두개 클래스의 인스턴스를 모두 선언하고 업데이트를 하기 전과 후를 비교하고있다. 별 생각을 안하고 본다면 처음 count를 0으로 받아오고 업데이트 메소드를 통해 해당 count를 1증가시켜서 출력이 1이 나와야하는거 아닌가 싶지만,
myUpdater.update(myCounter.count); 를 보면 기존의 count값인 0이 update메소드 안으로 들어가 count를 1 증가시키지만, 여기서의 count는 원본이아니라 update메소드 안으로 새롭게 복사된 count이다. 따라서 원본count에 전혀 영향을 주지 못하는것이다.
- Call by reference
위의 코드를 아래와 같이 변경했다.
class Updater {
void update(Counter counter) {
counter.count++;
}
}
class Counter {
int count = 0; // 객체변수
}
public class Sample {
public static void main(String[] args) {
Counter myCounter = new Counter();
System.out.println("before update:"+myCounter.count);
Updater myUpdater = new Updater();
myUpdater.update(myCounter);
System.out.println("after update:"+myCounter.count);
}
}
위의 코드와 차이점은 update메소드의 파라미터가 기본형인 int에서 참조형인 Class로 바뀌었다. 참조형은 가르키고있는 대상의 주소를 복사한다. 따라서 Call by value와 달리 실제로 count값이 변경된다.
before update:0
after update:1
- 자바에서의 Call by value
- 얼핏 생각하면 자바에서도 참조형이 있으니 Call by reference가 존재하는것이 아니냐 라고 이야기할 수 있지만
자바에는 오로지 Call by value밖에 없다. 주소값을 직접 참조하는 것이 아닌, 주소값을 복사하고 나니 복사된 주소값을 참조할 수 있어 주소값이 가르키는 객체의 내용을 변경할 수 있는 것이다. - 이에 따라 세간에서는 이 방식을 직접적인 참조가 아니기 때문에 Call by Address라고 부르기도 한다.
- 정리하자면,
Call by value : 파라미터로 전달받은 값을 복사
Call by reference : 파라미터로 전달받은 값을 직접 참조
Call by Address : 파라미터로 전달받은 주소값을 복사
'Java' 카테고리의 다른 글
[Java] 함수형 인터페이스(Functional Interface)와 람다식(Lambda Expression) (0) | 2023.12.14 |
---|---|
[Java] 추상 클래스와 인터페이스 (0) | 2023.05.30 |
[Java] for each문 & switch/case문 (0) | 2023.05.25 |
[Java] Class (클래스), Method (메소드), 생성자 (0) | 2023.05.24 |
[Java] 자료형 (Map, Set) (0) | 2023.05.24 |