[Java] 자바는 call by value 일까 call by reference 일까 ?

FeelingXD·2023년 9월 2일
1

JAVA

목록 보기
4/4
post-thumbnail

자바의 primitive 타입은 call by value , wrapper class 는 call by reference 라고 생각 하고 있었다.
정말 그런지 테스트하고 검증하여 알아보자.😅

TL; DR

우선 결과부터 말하면 자바는 모든경우에서 call by value 이다.
테스트를 통해서 알아보자.

Test Codes

다음 코든는 테스트에 사용될 name 필드를가지는 Dog 클래스이다.

@Getter
@Setter
@AllArgsConstructor
public class Dog {
  public  String name;
}

위의 Dog 클래스를 이용하여 call by reference, value 인지 확인하는 테스트를 진행 하였다.

@Slf4j
class DogTest {
  @Test
  @DisplayName("Call by Reference 일경우 원본 변화가 생긴다.")
  void call_by_test(){
    //given
    //when
    Dog dog=new Dog("foo");

    log.info("start name is .. :"+dog.getName());// foo
    foo(dog);
    log.info("end name is .. :"+dog.getName()); // foo -> expected asdf  actual : foo
    log.info("set new dog .. :"+dog.getName()); // foo

    //then
  }
  
  public void foo(Dog dog){

    Dog tmp=new Dog("asdf");
    dog=tmp; // call by reference 일 경우 dog 메모리를 tmp에 대입한다. (원본에 영향을 준다.)
    dog.setName("var");
    log.info("changed name is.. :"+dog.getName());
  }

call by value 일 경우

foo 메서드 가 끝나더 라도 foo 에서 dog = tmp 를 대입하더라도 call_by test에 돌아왔을때 원본의 변화가 없을 것이다.

call by reference 일 경우

foo 메서드가 call by reference로 동작한다면

foo 메서드 실행시 dog라는 참조에 tmp를 대입 하므로 foo 메서드가 끝나더라도

foo 메서드를 호출한 call_by_test 에서도 dog 내용의 변화에 영향이 있을것이다.

foo 에서는 tmp로 새로운 Dog 객체를 생성 한 후 파라미터 dog 에 대입했다.

call by reference 일 경우 원본에 변화가 있을 것 이다.

어떤식으로 동작하는 걸까?

call by test 에서

foo 메서드 실행시


1. foo 메서드가 실행되면서 foo 에서 foo의 주소값을 '복사' 한 dog 변수를 가진다. 이때 call by test의 dog 와 foo 의 dog 는 같은 객체를 가르킨다.

  1. tmp 라는 새로운 Dog 객체를 만들고 dog 에 대입하면 위와 같이 동작한다.

  2. foo 가 실행이 끝나면 tmp 는 더이상 가르키는 멤버 변수가 없으므로 GC에 의해서 지워진다.

  3. call by test 의 dog 객체는 변하지 않는다.

결론

  • 이로써 자바의 메서드 실행시 원시타입, 객체타입 모두 call by value로 호출 되는걸 알수있었다. 더 정확하게말하면 pass by value ( 값으로써 넘기기) 로 표현이 좋을것 같다.
  • 호출자 와 수신자 변수는 각각 heap의 객체를 가르키는 변수일뿐 heap 자체가 아니므로 재할당이 일어나더라도 heap 의 객체는 변하지않는다. (객체의 메서드를 사용 해서 내용 을 변경할수는있다.)

참고한 글들

profile
tistory로 이사갑니다. :) https://feelingxd.tistory.com/

1개의 댓글

comment-user-thumbnail
2023년 9월 2일

완전히 이해해 버렸네요 :)

답글 달기