공부/Java

Java가 Call by reference가 아니라 Call by Value 인 이유

2020. 8. 20. 23:55

java가 call by reference가 아니라 call by value인 이유를 알아보겠습니다.

call by reference : 참조에 의한 호출, 함수에서 인자 값을 넘길 때 레퍼런스(객체를 참조하는 주소)를 넘김.

call by value : 값에 의한 호출, 함수에서 인자 값을 넘길 때 값을 복사해서 넘김.

 

 

먼저 예제 코드 전체를 보겠습니다.


public class Main {

    public static void main(String[] args) {
        Persion personA = new Person("Choi");
        changeName(personA, "Park");
        System.out.println(personA.getName());	// Park
        changePerson(personA);
        System.out.println(personA.getName());	// Park
        resetPerson(persionA);
        System.out.println(personA.getName());	// Park
    }
    public static void changeName(Person person, String name) {
        person.setName(name);
    }
    public static void changePerson(Person person) {
        person = new Person("Kim");
    }
    public static void resetPerson(Person person) {
        person = null;
    }
}
class Person {
    private String name;
    public Person(String name) {
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
}

디버깅을 하며 하나하나 살펴보겠습니다.

 

6번 줄을 보면 main 메서드의 personA라는 변수가 참조하는 주소가 491번으로 나옵니다.

changeName 메서드로 들어가 보겠습니다.

 

메서드의 매개변수인 persion도 491번 주소를 참조하고 있습니다.

그래서 15번째 줄에서 491번 주소의 객체에 setName메서드를 실행시킵니다.

 

491번 주소의 객체 이름이 Park으로 바뀌었습니다.

main 메서드의 personA 변수도 491번 주소를 참조하고 있어 personA 변수도 이름 속성이 Park으로 바뀌게 됩니다.

 

따라서 8번 줄에서 Park이 출력됩니다.

여기서 잠깐, changeName 메서드가 실행되고 나서 personA의 속성이 변경되었기 때문에 call by reference 아닌가 라고 생각하게 됩니다. 하지만 changeName의 매개변수 가 personA의 변수 주소 자체를 가져가는 것이 아니라, changeName의 매개변수도 personA와 같은 주소를 참조하는 것입니다. 자세한 것은 아래에서 다시 설명해 보겠습니다.

 

changePerson 메서드에 들어왔습니다. 매개변수 person이 491번 주소를 참조하고 있습니다.

18번 줄을 타게 되면 새로운 Person이라는 객체를 생성한 뒤 그 주소를 person가 참조하도록 할 것입니다.

 

변수 person이 참조하는 주소가 493번으로 변경되었습니다.

여기서 java가 call by value라는 것을 알게 됩니다. 메서드의 매개변수는 호출 시 전달받은 인자의 주소를 참조하며 메서드 내에서만 사용되는 지역 변수입니다. 따라서 해당 변수에 어떠한 값을 대입해도 호출한 변수에는 영향이 미치지 않습니다.

 

위의 resetPerson 메서드를 보면 처음 person 변수는 491번 주소를 참조하고 있습니다.

 

아래 21번 줄이 실행되면 person 변수는 null로 아무 변수도 참조하지 않는 상태가 됩니다.

 

메서드들이 실행되면서 매개변수가 어떠한 값을 참조하고 값이 바뀌는지 간단히 정리한 표입니다.

 

이상으로 java가 call by value인 이유에 대해 정리해 보았습니다.

잘못된 부분도 있을 수 있으니 의견은 감사히 받겠습니다. 많은 도움이 되었으면 좋겠습니다 감사합니다.

 

 

※ persion -> person 오타 수정

반응형