반응형
작성 전
우선 Java는 모두 다 Call By Value가 맞다.(개인 의견이 아닌, Java 언어의 창시자 제임스 고슬링이 Java 언어를 개발할 때 Call By Value만 참고하였다고 한다 하지만 “아무도 믿지마” 라는 마음가짐으로 작성하였습니다.\
http://fredosaurus.com/JavaBasics/methods/method-commentary/methcom-20-passby.html
알아두어야 할 지식
Primitive Type
- stack 영역에 변수 값 저장
Reference Type
- heap 영역에 저장된 오브젝트의 메모리 주소를 stack 영역에 저장
작동 방식
Primitive Type을 매개변수로 전달할 때
main 메소드에서 modify(x,y) 메소드호출 시.
public void modify(int x1, int y1) {
x1 = 5;
y1 = 10;
}
@Test
void 원시타입호출() {
int x = 1;
int y = 2;
modify(x, y);
Assertions.assertEquals(x, 1);
Assertions.assertEquals(y, 2);
}
x,y 값 변화없음.(call by Value 맞음)
reference Type을 매개변수로 전달할 때
해당 타입이 혼란을 줍니다.
초기 상태
@Test
public void 참조타입호출() {
Foo a = new Foo(1);
Foo b = new Foo(1);
// Before Modification
Assertions.assertEquals(a.num, 1);
Assertions.assertEquals(b.num, 1);
}
class Foo {
public int num;
public Foo(int num) {
this.num = num;
}
}
modify 메소드 호출 됐을 시점 상태
public static void modify(Foo a1, Foo b1) {
}
@Test
public void 참조타입호출() {
Foo a = new Foo(1);
Foo b = new Foo(1);
// Before Modification
Assertions.assertEquals(a.num, 1);
Assertions.assertEquals(b.num, 1);
modify(a, b);
}
class Foo {
public int num;
public Foo(int num) {
this.num = num;
}
}
- 같은 heap 영역(stack 영역에서 가르키는 heap 영역의 주소)을 가르킴
modify 메소드 기능 실행
**public static void modify(Foo a1, Foo b1) {
a1.num++;
// 새로 객체를 생성함.
b1 = new Foo(1);
b1.num++;
}
@Test
public void 참조타입호출() {
Foo a = new Foo(1);
Foo b = new Foo(1);
// Before Modification
Assertions.assertEquals(a.num, 1);
Assertions.assertEquals(b.num, 1);
modify(a, b);
// After Modification
Assertions.assertEquals(a.num, 2);
Assertions.assertEquals(b.num, 1);
}
class Foo {
public int num;
public Foo(int num) {
this.num = num;
}
}**
- b의 변수와 b1의 변수는 다른 heap 영역을 가르키게 됨
의문점(reference Type 케이스)
- a1, b1의 변수가 a,b의 변수가 가르키는 heap영역(메모리 주소)가 같으니 call by reference가 맞다.
- 실제로 a1변수에서 a.num 값을 증가시켜 a변수의 num 값이 증가가 된것이 call by reference의 근거
Call by Reference란?
정확히 해당 개념이 어디서 시작되었는진 잘 모르겠으나, 유명한 C++으로 예시로 듬
#include <stdio.h>
// 여기서 "&"는 변수의 주소값을 확인할수있는 C 문법
void swapnum(int &i, int &j) {
int temp = i;
i = j;
j = temp;
}
int main(void) {
int a = 10;
int b = 20;
swapnum(a, b);
printf("A is %d and B is %d\\n", a, b);
return 0;
}
결과
result : A is 20 and B is 10
다시 돌아가서.
- 결국 Call by Reference는 해당 변수가 저장되어있는 실제 메모리 주소를 동일하게 참조하느냐임
- C++을 Java로 비유하자면, swapnum 함수에서 실행된 swap 기능은 main 함수에 영향이 없어야함. (변수가 가르키는 메모리 주소를 변경했기 때문에 a1.num++ 작업하고는 의미가 다릅니다.)
참고사이트
- JAVA
Pass-By-Value as a Parameter Passing Mechanism in Java | Baeldung
- C++
반응형
'Java' 카테고리의 다른 글
Spring의 탄생배경 (0) | 2024.07.06 |
---|---|
[JAVA]Reference Type Cache 기능 (2) | 2024.01.04 |
[Spring]외장톰캣 특정 war 미로드 (0) | 2023.10.22 |
[Spring]PageRequest이용한 페이징처리 (0) | 2023.08.15 |
[QueryDSL]Q Class Import 불가 (0) | 2023.06.02 |