본문 바로가기

StackOverflow

[Java] 자바는 "pass-by-reference" 인가요, 아니면 "pass-bt-value"인가요?

http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value

이 글은 여기서 해석해 놓은 답변 말고도 다른 측면에서 달린 답글이 굉장히 많으니, 링크에 들어가서 보시길 권장드립니다.



Q: 자바는 "pass-by-reference" 인가요, 아니면 "pass-bt-value"인가요?

저는 자바가 pass-by-reference 라고 생각했습니다. 

(역주: 변수를 파라메터로 값을 전달할 때, 원래 것의 참조값을 넘기는 방식. 이 경우 전달받은 쪽에서 그 파라메터를 변경하면, 전달해 준 쪽에서 가지고 있는 변수도 같이 변경됨.)

근데 다른 블로그를 보니, 그렇지 않다고 합니다. 이해하지 못하겠네요.

누가 설명 좀 해주시겠어요?

(질문자: user4315community wiki)



A: 자바는 항상 pass-by-value입니다.

안타깝게도 포인터의 레퍼런스를 넘기기 때문에, 여기서 초보자들이 헷갈릴 수 있습니다. 왜냐하면 이 레퍼런스가 pass by value 방식으로 전달되기 때문입니다.

아래 예제를 보세요.

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

    if (aDog.getName().equals("Max")) { //true
        System.out.println( "Java passes by value." );

    } else if (aDog.getName().equals("Fifi")) {
        System.out.println( "Java passes by reference." );
    }
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true

    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

이 예제에서, aDog.getName()은 "MAX"를 리턴할겁니다. 

메인에서 가지고 있는 aDog 변수는 

- foo() 메소드안에서 새로 생성되고, 이름이 "Fifi"로 정의되지만

- 원래 메인에 있던 aDog 변수의 이름은 여전히 "Max"이고, 변경되지 않습니다.


하지만, 아래와 같이 전달받은 레퍼런스를 이용해 그것이 가지고 있는 값을 변경하는 것은 가능합니다.

Dog aDog = new Dog("Max");
foo(aDog);
aDog.getName().equals("Fifi"); // true

public void foo(Dog d) {
    d.getName().equals("Max"); // true
    d.setName("Fifi");
}

(역주: 오브젝트인 파라메터를 전달 할 경우, 

(1) 그 오브젝트가 가지고 있는 값을 변경하는 것은 가능합니다.

(2) 하지만 new를 이용해 새로 생성하거나, 다른 오브젝트를 대입한다해도 원래 파라메터의 값은 해당 메소드 밖에서는 그대로입니다.

)



(답변자: erlando,community wiki)


_

I always thought Java was pass-by-reference; however I've seen a couple of blog posts (for example, this blog) that claim it's not. I do not think I understand the distinction they are making.

What is the explanation?

shareeditflag

_

Java is always pass-by-value. Unfortunately, they decided to call pointers references, thus confusing newbies. Because those references are passed by value.

It goes like this:

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

    if (aDog.getName().equals("Max")) { //true
        System.out.println( "Java passes by value." );

    } else if (aDog.getName().equals("Fifi")) {
        System.out.println( "Java passes by reference." );
    }
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true

    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

In this example aDog.getName() will still return "Max". The value aDog within main is not overwritten 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:

Dog aDog = new Dog("Max");
foo(aDog);
aDog.getName().equals("Fifi"); // true

public void foo(Dog d) {
    d.getName().equals("Max"); // true
    d.setName("Fifi");
}
shareeditflag