Language/Java

Is Java “pass-by-reference” or “pass-by-value”? | Stack Overflow 정리

이웃비 2020. 12. 13. 06:52
본 내용은 Stack Overflow의 한국어 번역이 아니며, 개인적인 공부를 위해 Stack Overflow 질의를 정리한 내용입니다

 

 

 질문 

자바는 'pass-by-refence'인가요, 'pass-by-value'인가요?

I always thought Java uses pass-by-reference.

However, I've seen a couple of blog posts (for example, this blog) that claim that it isn't (the blog post says that Java uses pass-by-value).

I don't think I understand the distinction they're making.

What is the explanation?

 


나는 Java가 pass-by-reference 방식을 사용한다고 생각했습니다. 그러나 몇개의 블로그를 보니, 자바는 pass-by-value를 사용한다고 합니다. 왜 그렇게 말하는 건가요?

 

 

 답변 

 

Java is always pass-by-value.
Unfortunately, we never handle an object at all, instead juggling object-handles called references (which are passed by value of course). The chosen terminology and semantics easily confuse many beginners.

It goes like this:


 

Java는 항상 값을 전달합니다. 안타깝게도 초보자들은 이 용어를 혼돈합니다. 다음 예시를 보시죠.

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    // we pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true
    aDog.getName().equals("Fifi"); // false
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // change d inside of foo() to point to a new Dog instance "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

 

 

 

In the example above aDog.getName() will still return "Max". The value aDog within main is not changed in the function foo with the Dog "Fifi" as the object reference is passed by value.

If it were passed by reference, then the aDog.getName() in main would return "Fifi" after the call to foo.

Likewise:


 

위의 예에서 aDog.getName()은 여전히 'Max'를  return합니다. main에서의 aDog는 foo라는 함수에 의해 값이 FiFi로 바뀌지 않습니다. FiFi를 참조하게 하고 싶다면, foo()메서드 이후에 main에서 aDog.getName()를 썼을 때 FiFi를 리턴하게끔 하면 됩니다. 그 방법은 이렇습니다.

 

 

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
    // but it is still the same dog:
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // this changes the name of d to be "Fifi"
    d.setName("Fifi");
}

 

 

In the above example, Fifi is the dog's name after call to foo(aDog) because the object's name was set inside of foo(...). Any operations that foo performs on d are such that, for all practical purposes, they are performed on aDog, but it is not possible to change the value of the variable aDog itself.

 


 

위 예시에서, foo()메서드 이후에 FiFi가 dog's name이 된 것은 foo()메서드 안에서 그렇게 설정되었기 때문입니다. 그러나 aDog가 바뀐 것이 아니고, aDog가 가리키는 값이 변한 것입니다.