TY blog

참조형 타입과 Call by Value 본문

프로그래밍 언어/JAVA

참조형 타입과 Call by Value

주짓수하는 개발자 2024. 2. 11. 23:04

Java에서 배열은 참조형(reference) 타입으로 배열을 메서드에 인자로 전달할 때 

Call by reference 방식으로 작동한다고 생각할 수 있지만 모든 변수는 Call by value 방식으로 동작합니다.

 

Call by value 

 

변수 자체가 아닌 변수에 저장된 값이 메서드에 전달되는 것을 의미 

참조형 변수의 경우 변수에 저장된 값은 객체의 reference이며 

배열을 메서드에 전달할 때 참조가 값으로 전달됩니다.

 

 

배열 예시코드
import java.util.Arrays;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5};

        System.out.println(Arrays.toString(array));    // 1. [1, 2, 3, 4, 5]
        replaceArrayValue(array);
        System.out.println(Arrays.toString(array));     // 2. [1, 2, 10, 4, 5]
        replaceArrayReference(array);
        System.out.println(Arrays.toString(array));     // 3. [1, 2, 3, 4, 5]
    }

    public static void replaceArrayValue(int[] arr) {
        arr[3] = 10;
    }

    public static void replaceArrayReference(int[] arr) {
        arr = new int[]{5, 4, 3, 2, 1};
    }
}

 

배열의 참조(reference)가 값으로 전달되므로, 메서드 내에서 배열의 요소를 변경하면 원래 배열에 영향을 미치지만, 메서드 내에서 배열 변수를 다른 배열을 참조하도록 변경해도, Call by Value 방식으로 원래 배열에 영향을 미치지 않는다.

 

String 예시코드
public class Main {
    public static void main(String[] args) {
        String s = "Hello World";
        System.out.println(s);  // 1. Hello World
        replaceStringValue(s);
        System.out.println(s);  // 2. Hello World
        replaceStringReference(s);
        System.out.println(s);  // 3. Hello World

        String s2 = s;
        System.out.println(s2); // 4. Hello World
        s2 = null;              // (Call by value 확인하는 코드)
        System.out.println(s);  // 5. Hello World
        System.out.println(s2); // null
    }

    public static void replaceStringValue(String s) {
        s = "HI";
    }

    public static void replaceStringReference(String s) {
        s = new String("NICE");
    }
}

 

replaceStringValue 함수에서 s = "HI"로 바꿨지만 원본에 영향을 주지 않는다.

그 이유는 String 타입은 immutable 한 성질을 가지고 있어 변경이 불가능하지만 할당될 때마다 객체를 생성하기 때문에 변경이 되는 것처럼 보이는데 실제로는 new String("HI") 코드로 동작되어 값이 변경되지 않은 것이다. 

Comments