Java Code → .class → JVM 위에서 실행됩니다.
visibility
를 가집니다.Wrapper Class - Integer, Double, String...
이들은 모두 Immutable
합니다.
Heap에 있는 같은 오브젝트를 레퍼런스 하고 있는 경우라도, 새로운 연산이 적용된 순간!
새로운 오브젝트가 Heap에 할당 됩니다.
// ❓ 문제1. after a의 결과 출력값은?
@Test
void printReferenceInteger() {
Integer a = 10;
System.out.println("before: " + a);
changeInteger(a);
System.out.println("after: " + a);
}
private void changeInteger(Integer num) {
num += 10;
}
// ❓ 문제2. after s의 결과 출력값은?
@Test
void printReferenceString() {
String s = "hello";
changeString(s);
System.out.println(s);
}
private static void changeString(String str) {
str += " world";
}
위의 결과는 아래와 같습니다.
| 문제 1 : after: 10
| 문제 2 : hello
왓더...!? 변하지 않았다. 머선129 🤔
아래의 그림을 살펴봅시다.
그리고 마지막으로 메서드를 벗어나게 되면, num이라는 값은 stack에서 사라지게 됩니다.
method라는 지역에서 벗어났기 때문이죠.
보시다시피 a라는 녀석은 여전히 10을 참조하고 있기 때문에, 값이 변하지 않은 채로 그대로 출력되게 되는 것이옵니다.
Java에는 Call by reference가 없다고 합니다.
하지만 매개변수로 받아서 값이 변하는 경우는 무엇일까요?
class Sample {
public int value;
Sample(int num) {
value = num;
}
}
class Main {
public static void main(String[] args) {
Sample sam = new Sample(10);
run(sam);
System.out.println(sam.value); // 🔎 어떤 값이 출력 될까요?
}
static void run(Sample sample) {
sample.value = 20;
}
}
결과값은 20인 값이 출력 되게 됩니다.
그럼 Call by reference인것 아닌가?! → 아닙니다.
이렇게 주소라는 값을 복제하였기 때문에, 변경이 되는 것입니다.
즉 이건 Call by value라고 볼 수 있습니다.
그래서 결론은? 'Java에 Call by reference는 없다.' 입니다.