기본형 매개변수와 참조형 매개변수

growdeveloper ㅣ 2022. 8. 11. 15:59

자바에서는 메소드를 호출할 대 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨준다. 매개변수의 타입이 기본형(primitive type) 일 때는 기본형 값이 복사되겠지만,참조형 (reference type) 이면 인스턴스의 주소가 복사된다. 메서드의 매개변수를 기본형으로 선언하면 단순히 저장된 값만 얻지만, 참조형으로 선언하면 값이 저장된 곳의 주소를 알 수 있기 때문에 값을 읽어 오는 것은 물론 값을 변경 하는 것도 가능하다.

기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.(read only)
참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다.(read & write)
class Data {
  int x;
}

public class PrimitiveParamEx {
  public static void main(String[] args) {
    Data d = new Data();
    d.x = 10;
    System.out.println("main:() : x =" + d.x);

    change(d.x);
    System.out.println("after change(d.x)");
    System.out.println("main() : x = " + d.x);
  }

  static void change(int x) {
    x = 1000;
    System.out.println("change() : x = " + x);
  }
}
 
 
main:() : x =10
change() : x = 1000
after change(d.x)  
main() : x = 10

 

①change메서드가 호출 되면서 d.x가 change 메서드의 매개변수 x에 복사됨

②change메서드에서 x의 값을 1000으로 변경

③change메서드가 종료되면서 매개변수 x는 스택에서 제거됨.


'd.x'의 값이 변경된 것이 아니라. change메서드의 매개변수 x의 값이 변경된 것이다. 즉, 원본이 아닌 복사본이 변경된 것이라 원본에는 아무런 영향을 미치지 못한다. 이처럼 기본형 매개변수는 변수에 저장된 값만 읽을 수만 있을 뿐 변경할 수는 없다.

package ch6;
class Data {
  int x;
}

public class ReferenceParamEx {
  public static void main(String[] args) {
    Data d = new Data();
    d.x = 10;
    System.out.println("main:() : x =" + d.x);

    change(d);
    System.out.println("after change(d.x)");
    System.out.println("main() : x = " + d.x);
  }

  static void change(Data d) {
    d.x = 1000;
    System.out.println("change() : x = " + d.x);
  }
}

main:() : x =10
change() : x = 1000
after change(d.x)  
main() : x = 1000

① change메서드가 호출되면서 참조변수 d의 값(주소)이 매개변수 d에 복사됨. 이제 매개변수 d에 저장된 주소값으로 x에 접근이 가능

②change 메서드에서 매개변수 d로 x의 값을 1000으로 변경

③change 메서드가 종료되면서 매개변수 d는 스택에서 제거됨.


public class PrimitiveParamEx2 {
  public static void main(String[] args) {
    int[] x = { 10 };

    System.out.println("main:() : x =" + x[0]);

    change(x);
    System.out.println("after change(x)");
    System.out.println("main() : x = " + x[0]);
  }

  static void change(int[] x) {
    x[0] = 1000;
    System.out.println("change() : x = " + x[0]);
  }
}
main:() : x =10
change() : x = 1000       
after change(x)
main() : x = 1000

이전의 참조형 매개변수 예제를 배열을 이용하도록 변경 하였다. 배열도 객체와 같이 참조변수를 통해 데이터가 저장된 공간에 접근한다는 것을 이미 배웠다. 임시적으로 간단히 처리할 때는 별도의 클래스를 선언하는 것보다 이처럼 배열을 이용할 수도 있다.


package ch6;

public class PrimitiveParamEx3 {
  public static void main(String[] args) {
    int[] arr = new int[] { 3, 2, 1, 6, 5, 4 };

    printArr(arr); // 배열의 모든 요소를 출력
    sortArr(arr); // 배열을 정렬
    printArr(arr); // 배열을 정렬후 모든 요소를 출력
    System.out.println("sum=" + sumArr(arr));

  }

  static void printArr(int[] arr) {
    System.out.print("[");

    for (int i : arr)
      System.out.print(i + ",");
    System.out.println("]");
  }

  static int sumArr(int[] arr) {
    int sum = 0;
    for (int i = 0; i < arr.length; i++)
      sum += arr[i];
    return sum;
  }

  static void sortArr(int[] arr) {
    for (int i = 0; i < arr.length - 1; i++) {
      for (int j = 0; j < arr.length - 1 - i; j++) {
        if (arr[j] > arr[j + 1]) {
          int tmp = arr[j];
          arr[j] = arr[j + 1];
          arr[j + 1] = tmp;
        }
      }
    }
  }// sortArr(int[] arr)

}
[3,2,1,6,5,4,]
[1,2,3,4,5,6,]
sum=21

메서드로 배열을 다루는 여라 가지 방법을 보여주는 예제이다. 매개변수의 타입이 배열이니까, 참조형 매개변수이다. 그래서 sortArr메서드에서 정렬한 것이 원래의 배열에 영향을 미친다.

public class ReturnTest {

  public static void main(String[] args) {
    ReturnTest r = new ReturnTest();

    int result = r.add(3, 5);
    System.out.println(result);

    int[] result2 = { 0 };
    r.add(3, 5, result2);
    System.out.println(result2[0]);
  }

  int add(int a, int b) {
    return a + b;
  }

  void add(int a, int b, int[] result) {
    result[0] = a + b;
  }

}
8
8

'자바' 카테고리의 다른 글

3.12 클래스 멤버와 인스턴스 멤버간의 참조와 호출  (0) 2022.08.27
클래스 메서드(static 메서드)와 인스턴스 메서드  (0) 2022.08.25
JVM의 메모리구조  (0) 2022.06.01
형변환  (0) 2022.06.01
변수의 타입  (0) 2022.05.08