[Java] Call by value / Call by reference ?

Carrot.___.·2024년 3월 4일
0

Call by value (값에 의한 호출)

  • 일반적으로 자바의 primitive type을 파라미터로 전달 시, 값에 의한 호출이 일어난다.

    public class CallByValue {
    	public static void main(String[] args) {
      	var callByValue = new CallByValue();
          int before = 10;
          int after = 15;
          
          System.out.println("Before Change : " + before);
          callByValue.changeValue(before, after);
          System.out.println("After Change : " + before);
      }
      
      void changeValue(int target, int toChange) {
      	target = toChange;
          System.out.println("In Change : " + target);
      }    
    /* 출력 결과
    Before Change : 10
    In Change : 15
    After Change : 10
    */
    }

    위 예제를 보면 알 수 있듯이, primitive type은 changeValue 함수는 before 변수의 값을 바꿀 수 없다. 이는, changeValue() 메서드 호출 시, 스택 프레임이 생성되고, 파라미터의 값을 직접 복사하여, 새로운 메모리에 할당된다. 따라서, 실제 before의 값의 변화는 없다.

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

  • 일반적으로 자바의 클래스(참조 타입)을 파라미터로 전달 시, 주소 값을 복사하여 전달한다.

    public class CallByReference {
     	public static void main(String[] args) {
         	CallByReference callByReference = new CallByReference();
         	int before = 10;
         	int after = 15;
         	TestClass testClass = new TestClass(before);
         	System.out.println("[Before]" + testClass + " : " + testClass.value);
         	callByReference.changeValue(testClass, after);
         	System.out.println("[After]" + testClass + " : " + testClass.value);
     	}
    
     	void changeValue(TestClass testClass, int toChange) {
         	testClass.value = toChange;
         	System.out.println("[In Change]" + testClass + " : " + testClass.value);
     	}
    
     	static class TestClass {
         	int value;
    
         	public TestClass(int value) {
             	this.value = value;
         	}
     	}
    }
    
    /* 출력결과
    [Before]org.example.CallByReference$TestClass@1 : 10
    [In Change]org.example.CallByReference$TestClass@1 : 15
    [After]org.example.CallByReference$TestClass@1 : 15
    */
    

    위 예제를 보면, changeValue 메서드 호출시, 실제 값이 변경되는 것을 볼 수 있다.
    모든 클래스는 Object를 상속받으므로, Object의 toString() 메서드를 살펴보면 다음과 같다.
    기본적으로, toString()을 오버라이딩하지 않으면, {className}@{hashcode}로 리턴되는 것을 알 수 있습니다. 따라서, changeValue 메서드에서는 파라미터로 전달된 참조 타입은 해당 주소 값을 복사하여, 객체를 참조합니다. 최종적으로 결과가 바뀐 것을 알 수 있습니다.

0개의 댓글