본문 바로가기
JAVA

[자바/JAVA] - 기본형(Primitive Type)과 참조형(Reference Type)이란?

by wook99 2024. 5. 25.

변수의 데이터 타입에는 크게 기본형과 참조형이 있다.

 

1. 정의

기본형(Primitive Type) : 사용할 값을 직접 넣을 수 있는 데이터 타입

ex) int, long, double, boolean

 

참조형(Reference Type) : 데이터에 접근하기 위한 참조값을 저장하는 데이터 타입

ex) Student student, 배열

 

기본형을 제외한 나머지는 모두 참조형이라고 이해할 수 있다.

 

2. 사용

1) 기본형

  • 숫자 1,2,3 같이 실제 사용하는 값을 변수에 담을 수 있음. 따라서 해당 값을 바로 사용할 수 있다.
  • 계산에 그대로 사용할 수 있다.

2) 참조형

  • 참조값은 실제 사용하는 값이 아닌 객체의 참조(위치, 주소)를 저장하기 떄문에 콜론(.)을 통해 객체에 접근해서 사용할 수 있다.
  • 참조형 변수를 그대로 사용하여 계산할 수 없다. 객체에 접근해야 계산을 하던 말던 할 수 있다.

 

3. String

String은 사실 클래스이고, 참조형이다. 하지만 String은 문자 값을 바로 사용할 수 있고, 계산도 가능하다. 문자는 매우 자주 다루기 떄문에 자바에서 편의 기능을 제공한 것이다.

 


4. 기본형과 참조형 변수의 대입

 

아래는 기본형 변수의 대입을 이해하기 위해 작성한 코드이다. 이해에 무리는 없을 것이다.

public class VarChange1 {
    public static void main(String[] args) {
        int a = 10;
        int b = a;

        System.out.println("a = " + a);
        System.out.println("b = " + b);

        a = 20;
        System.out.println("------------a변경-------------");
        System.out.println("a = " + a);
        System.out.println("b = " + b);

        b = 30;
        System.out.println("------------b변경-------------");
        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }
}


/* 출력 결과
a = 10
b = 10
------------a변경-------------
a = 20
b = 10
------------b변경-------------
a = 20
b = 30
*/

 

 

아래는 참조형 변수의 대입을 설명하기 위해 작성한 코드이다.

public class Data {
    int value;
}
public class VarChange2 {
    public static void main(String[] args) {
        Data dataA = new Data();
        dataA.value = 10;
        Data dataB = dataA;

        System.out.println("dataA 참조값 = " + dataA);
        System.out.println("dataB 참조값 = " + dataB);
        System.out.println("dataA.value = " + dataA.value);
        System.out.println("dataB.value = " + dataB.value);

        System.out.println("------------------A변경-----------------");
        dataA.value = 20;
        System.out.println("dataA.value = " + dataA.value);
        System.out.println("dataB.value = " + dataB.value);

        System.out.println("------------------B변경-----------------");
        dataB.value = 30;
        System.out.println("dataA.value = " + dataA.value);
        System.out.println("dataB.value = " + dataB.value);
    }
}

/* 출력 결과
dataA 참조값 = ref.Data@10f87f48
dataB 참조값 = ref.Data@10f87f48
dataA.value = 10
dataB.value = 10
------------------A변경-----------------
dataA.value = 20
dataB.value = 20
------------------B변경-----------------
dataA.value = 30
dataB.value = 30
*/

 

dataA에는 참조값이 들어있고, value에 10이라는 값을 초기화해주었다.

dataB에 dataA의 값(참조값)을 대입해 주었다.

이로 인해 dataA와 dataB에는 같은 참조값이 들어있고, 같은 객체를 가리킨다는 것을 알 수 있다.

 

핵심 : dataA로 value에 접근하여 값을 수정하든, dataB로 접근하여 value를 수정하든, 같은 객체를 가리키기 때문에 dataA.value의 값과 dataB.value의 값을 동일하게 된다.

 


 

5. 메서드에서의 기본형 변수와 참조형 변수

1) 기본형

public class MethodChange1 {
    public static void main(String[] args) {
        int a = 10;
        System.out.println("메서드 호출 전 a = " + a);
        changePrimitive(a);
        System.out.println("메서드 호출 후 a = " + a);
    }

    static void changePrimitive(int x){
        x = 20;
    }
}

/* 출력 결과
메서드 호출 전 a = 10
메서드 호출 후 a = 10
*/

 

왜 메서드 호출 후 a의 값이 20으로 바뀌지 않지?라고 생각할 수도 있다.

x는 a의 값을 공유하는게 아니고, a의 값을 복사해서 x에 대입한 것이기 때문에, a와 x는 각각 다른 변수이며, 각각 10을 가지게 된 것이다. 따라서 x의 값을 20을 대입해주면 a에는 그대로 10, x에는 20이 되는 것이다.

 

changePrimitive 메서드가 끝난 뒤에는 x는 메모리에서 제거된다.

 

 

2) 참조형

public class MethodChange2 {
    public static void main(String[] args) {
        Data dataA  = new Data();
        dataA.value = 10;
        System.out.println("메서드 호출 전 dataA = " + dataA.value);
        System.out.println("dataA = " + dataA);
        changeReference(dataA);
        System.out.println("메서드 호출 후 dataA = " + dataA.value);
    }

    static void changeReference(Data dataX){
        System.out.println("dataX = " + dataX);
        dataX.value = 20;
    }
}

/*출력 결과
메서드 호출 전 dataA = 10
dataA = ref.Data@52cc8049
dataX = ref.Data@52cc8049
메서드 호출 후 dataA = 20
*/

 

changeReference를 통해 dataA의 값은 dataX에 값에 대입된다.

dataA의 값에는 객체의 주소 값이 들어있었기 때문에 dataX도 dataA와 같은 객체를 가리키게 된다.

따라서 dataX를 통해 dataA가 가리키는 객체에 접근할 수 있고, dataA객체의 value값에도 영향을 미친 것이다.

 

자바의 대원칙인 "자바는 항상 변수의 값을 복사해서 대입한다." 를 기억하고 있다면 이해가 훨씬 쉬울 것이다.