Call by Value, Call by Reference

민선규·2023년 4월 3일
0

JAVA

목록 보기
12/25
post-thumbnail

이번에는 함수를 호출 할 때 파라미터를 넘기는 방법으로 Call by Value와 Call by Reference에 대해서 정리를 해보았다.

Call by Value(값에 의한 호출)

  • 파라미터로 복사한 값을 넘기는 방법으로 인수와 파라미터가 서로 다른 변수로 존재하는 방식이다.
  • 파라미터로 넘어온 값을 수정을 하여도 인수의 값은 변함이 없다.

Call by Reference(참조에 의한 호출)

  • 파라미터로 참조(주소)를 넘기는 방법으로 하나의 변수를 공유하는 방식이다.
  • 파라미터로 넘어온 값을 수정하면 인수의 값도 수정된다.

Java에서는?

Java언어에서는 Primitive 타입을 전달할 때는 원본에 영향을 끼치지 않고 Reference 타입을 전달할 때는 원본에 영향을 끼치므로 Call by Value와 Call by Reference를 적절히 사용하는 언어인가 생각을 할 수 있다. 나 또한 오히려 Call by Reference에 가깝지 않은가 생각을 해왔지만 이번에 학습을 하면서 제대로 배움을 얻게 되었다.

본론부터 말하면 Java는 Call by Value이다. 왜 Call by Value 인지 예시를 통해 설명을 적어보겠다.

Java(Primitive Type)

public void Main(){
	int a = 10;
    int b = 5;
    
    Test(a, b);
	
    //a는 10, b는 5
	System.out.println("a는 " + a + ", " + "b는 " + b);
}

public void Test(int a, int b){
	a = 20;
    b = 10;
}

간단한 예제로 설명을 하자면 Main에서 Primitive 타입의 변수가 Stack 영역에 할당되고 각 각 10, 5 값을 가지게 된다. 그리고 Test 함수를 호출하면서 Primitive 타입의 변수가 새로 Stack 영역에 할당되고 값이 각 각 20, 10을 가지게 되는 것이다.

Stack에 별개로 생성된다는 것이 키워드이며 다만 초기값만 인수로 넘긴 값을 가지는 특징이다.

Java(Reference Type)

public void Main(){
	Person a = new Person(5);
    Person b = new Person(10);
    
    Test(a, b);
	
    //a의 나이는 6, b의 나이는 11
	System.out.println("a의 나이는 " + a.age + ", " + "b의 나이는 " + b.age);
}

public void Test(Person a, Person b){
	a.age++;
    b.age++;
}

public void Person{
	int age;
    public Person(int age){
    	this.age = age;
    }
}

이번에는 Primitive 타입이 아닌 Reference 타입일 때를 예시로 설명해 보았다. 위에 예제를 실행을 하게 된다면 Test 함수의 호출로 인해 원본데이터가 변하게 되어 a의 나이는 6, b의 나이는 11가 출력이 되며, Call by Reference가 아닌가? 라는 생각을 가질 수 있다.

public void Main(){
	Person a = new Person(5);
    Person b = new Person(10);
    
    Test(a, b);
	
    //a의 나이는 5, b의 나이는 10
	System.out.println("a의 나이는 " + a.age + ", " + "b의 나이는 " + b.age);
}

public void Test(Person a, Person b){
	a = new Person(10);
    b = new Person(20);
}

public void Person{
	int age;
    public Person(int age){
    	this.age = age;
    }
}

만약 Call by Reference 라면 위에 예시도 a의 나이는 10, b의 나이는 20이 출력이 되어야 하지만 실제로는 a의 나이는 5, b의 나이는 10이 출력이 된다.

Java(Reference Type)의 2가지 예시를 설명해 보겠다.

실제로 Reference Type을 인수로 넘길때는 참조를 넘기는 것이 아니라 주소값의 복사값이 인수로 넘어가며 Stack 영역에 같은 주소값을 가리키는 변수가 2개가 되는 것이다.

  • 첫 번째 예시에서 값이 변하는 이유는 2개의 변수가 하나의 인스턴스를 공유하고 있기 때문에 원본 또한 같은 인스턴스를 가리키므로 값이 변한 것이다.
  • 두 번째 예시에서 정말 참조를 넘기게 되었다면 a와 b에 새로운 인스턴스가 할당이 되고 원본 또한 새로운 인스턴스를 가리키게 되야하는데 실상은 원본은 기존 인스턴스를 가리키고 새로 스택에 할당된 변수가 새로운 인스턴스를 가리키게 된다.

참고 문서 및 링크

0개의 댓글

관련 채용 정보