안녕하세요. 성조입니다.
이번 포스팅은 전공 변경 이후에 처음 봤던 개념이며, 정의했던 내용이었는데 파이썬 기준으로는 정의를 해본 경험이 있지만 자바 언어를 기준으로 정리해 보지 않았던 것 같아서 시간 내서 정리해 봅니다.
잘못된 지식 전달 사항이 있다면 언제든지 댓글로 피드백 주시면 감사드리겠습니다.
결론
- Java는 기본적으로 Call by Value 방식을 사용한다. 그러나 객체 전달할 때는 참조가 전달되기 때문에 원본 객체의 내용을 변경하는 것이 가능한 것이다.
- Java는 포인터와 같은 직접적인 메모리 접근 방식이 없어서 C/C++ 에서와 같은 참조에 의한 호출은 정확하게 구현할 수 없다.
[정리]
비교 | Call by Value (값에 의한 참조) |
Call by Reference (주소에 의한 참조) |
전달 방식 | 변수를 전달할 때 값을 복사하여 전달함 | 메모리 주소 또는 참조를 통해서 데이터를 전달한다. |
변경 방식 | 값을 전달하는 방식이며, main에서 다른 메서드로 값을 전달하면 복사한 값을 전달한 것이며, 참조하고 있는 영역이 다르기 때문에 변경되지 않는다. | 메모리 주소나 참조를 통해 데이터를 전달하는 방식으로 메서드를 새로 생성해도 같은 메모리 주소를 공유하거나 참조하고 있기 때문에 값을 변경할 수 있다. |
Call by Value (값에 의한 호출)
Java는 기본적으로 'Call by Value' 방식을 사용하고 있다.
메서드로 변수를 전달할 때 값이 복사되어 전달되는 방식을 의미한다. 메서드에 전달된 값은 인자를 복사해서 보낸 것이므로 메서드 내에서 변경되더라도 원래 변수 값에는 영향을 미치지 않는다.
[예시 코드]
void updateValue(int value) {
value = 55;
}
public static void main(String[] args) {
int value = 23;
updateValue(value);
System.out.println(value); // 출력: 23
}
Java 코드를 실행시켜보면 주석처리한 것과 같이 출력 값으로 23이 나올 것이다.
값에 의한 호출 방식은 메서드에 값을 전달했다 하더라도 복사본이 전달되는 것이지. 실제 값을 조작하는 것이 아니다. 위 예제에서는 value 값을 100을 줘도 결국 value는 main 함수에서 처음 초기화 했던 값인 23을 출력한다.
즉, 기존 값을 새로운 복사 값으로 생성해서 메서드에 전달하는 호출 방식이다.
각자 생성된 값은 다른 메모리 영역을 가지고 있으므로 변수에 영향을 주지 않는다.
Call by Reference (참조에 의한 호출)
참조에 의한 호출은 메모리 주소나 참조를 통해서 데이터를 전달하는 방식이다. 전달된 참조를 통해 값을 변경하면 원래의 값도 영향을 받는 호출 방식이다. 즉, 생성된 메서드는 하나의 메모리 주소 또는 같은 곳을 참조를 하고 있는 것이다.
Java 언어는 기본으로 값에 의한 호출(Call by Value) 방법을 적용하지만. 객체가 새롭게 생성되는 것이 아니라면 참조에 의한 호출을 하는 경우. 객체가 바라보고 있는 메모리 주소 또는 참조가 동일하기 때문에 같은 영역을 수정하는 것이므로 참조에 의한 호출 방식으로 원래 객체에도 값 변경이라는 영향을 줄 수 있다.
[1. 예시 코드]
class Test {
int value;
}
void updateValue(Test test) {
test.value = 55;
}
public static void main(String[] args) {
Test test = new Test();
test.value = 23;
updateValue(test);
System.out.println(test.value); // 출력: 55
}
[2. 예시 코드]
class Box {
int width;
int height;
}
void updateBox(Box box) {
box.width = 10;
box.height = 20;
}
public static void main(String[] args) {
Box box = new Box();
box.width = 5;
box.height = 5;
updateBox(box);
System.out.println(box.width + ", " + box.height); // 출력: 10, 20
}
오타나 포스팅에 문제가 있다면 언제든지 댓글 남겨주시면 감사드립니다.
다음 포스팅 때 뵙겠습니다.
'Java ☕ > Java' 카테고리의 다른 글
[Java] 단일 책임 원칙(Single Responsibility Principle, SRP) (0) | 2023.05.29 |
---|---|
[Java] 박싱(Boxing)과 언박싱(Unboxing) (0) | 2023.05.28 |
[Java] 메소드 오버로딩과 오버라이딩 (with 아삭 한입 정리하기) (0) | 2023.05.23 |
[Java] 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy) (0) | 2021.12.14 |
[Java] 변수(Variable)와 상수(constant) (1) | 2021.11.30 |