[JAVA] 기본형 매개변수와 참조형 매개변수

kindof

·

2021. 7. 11. 22:52

1. 들어가면서

이번 시간에는 자바의 기본형 매개변수와 참조형 매개변수에 대해 알아보려고 합니다.

 

변수의 타입에 대해 공부했을 때 기본형(Primitive)와 참조형(Reference) 변수에 대해 살펴봤는데, 각각의 변수 타입이 매개변수로 입력될 때 어떻게 다른지 구체적으로 살펴보겠습니다.

 

2. 개념

자바에서는 메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨줍니다.

 

매개변수의 타입이 기본형(Primitive type)일 때는 기본형 값이 복사되겠지만, 참조형(reference type)이면 인스턴스의 주소가 복사되죠.

 

따라서, 메서드의 매개변수를 기본형으로 선언하면 단순히 저장된 값만 얻지만 참조형으로 선언하면 값이 저장된 곳의 주소를 알 수 있기 때문에 값을 읽어 오는 것은 물론 값을 변경하는 것도 가능해집니다.

class Data{
    int x;
}

public class parameterDemo {
    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);
    }
}

change 메서드에서 main메서드로부터 넘겨받은 d.x의 값을 1000으로 변경했는데도 main 메서드에서는 d.x값이 그대로입니다.

 

'd.x'의 값이 변경된 것이 아니라, change 메서드의 매개변수 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)");
        System.out.println("main(): x = " + d.x);
    }

    static void change(Data d) { // 참조형 매개변수
        d.x = 1000;
        System.out.println("change() : x = " + d.x);
    }
}

이전 예제와 달리 change 메서드를 호출한 후에 d.x의 값이 변경되었습니다.

 

change메서드의 매개변수가 참조형이라서 값이 아니라 '값이 저장된 주소' 를 change 메서드에게 넘겨주었기 때문에 값을 읽어오는 것뿐만 아니라 변경하는 것도 가능합니다.

 

참조형 매개변수에 대한 메서드 콜

 

위 그림은 참조형 매개변수를 메서드에 넘겼을 때 상황을 그림으로 나타낸 것입니다.

 

아래 예제는 반환값이 있는 메서드를 반환값이 없는 메서드로 바꾸는 방법을 보여줍니다. 참조형 매개변수를 이용하면 반환값이 없어도 메서드의 실행결과를 얻어올 수 있습니다.

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;
    }
}

 

3. 참조형 반환타입

매개변수뿐만 아니라 반환타입도 참조형이 될 수 있습니다.

 

특별할 것은 없고 메서드를 통해 참조형 변수를 리턴받아서 이 객체를 사용하려는 의도입니다.

public class ReferenceReturnEx {
    public static void main(String[] args) {
        Data d = new Data();
        d.x = 10;

        Data d2 = copy(d);
        System.out.println("d.x = "+d.x);        // d.x = 10
        System.out.println("d2.x = "+d2.x);     // d2.x = 10

    }
    static Data copy(Data d) { // 리턴 타입도 Data로 설정해야 한다.
        Data tmp = new Data();
        tmp.x = d.x;
        return tmp;
    }
}

copy 메서드 내에서 생성한 객체를 main 메서드에서 사용하려면, 이렇게 새로운 객체의 주소를 반환해줘야 합니다. 그렇지 않으면, copy 메서드가 종료되면서 새로운 객체의 참조가 사라지기 때문에 더 이상 객체를 사용할 방법이 없습니다.


이번 포스팅에서는 자바 기본형 변수와 참조형 변수의 매개변수, 반환타입에 대해 살펴봤습니다.

 

정말 기초적인 내용이지만, 가끔 가다보면 갑자기 객체의 변수값이 의도하지 않았는데 바뀌거나 객체의 변수를 바꾸고 싶었는데 바뀌지 않는 경우가 있죠. 기본형과 참조형 매개변수의 차이점에 대해 항상 염두하면서 실수하지 말아야겠습니다🙄