Java/김영한의 실전자바

[김영한의 실전 자바 - 기본편] 기본형과 참조형

슈코 2024. 1. 21. 21:25

기본형과 참조형

기본형과 참조형 또한 자바를 공부하면서 반드시 이해하고 넘어가야 하는 내용이다.

내용 자체는 어렵지 않지만, 헷갈릴 수 있기 때문에 한번 정리하고 넘어간다.

 

기본형(Primitive Type)
int, long, double, boolean과 같이 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입

 

참조형(Reference Type)
클래스, 배열과 같이 데이터에 접근하기 위한 주소값을 저장하는 데이터 타입
( Student student, int[] students )

 

기본형 = 데이터의 값을 넣을 수 있는 데이터 타입

참조형 = 데이터의 주소값을 넣을 수 있는 데이터 타입

 

기본형은 변수에 값을 직접 넣어서, 참조형은 변수에 주소값을 넣어서 그 주소를 참조해 사용한다

public static void main(String[] args) {

    int value = 5;
    System.out.println("value = " + value);

    int[] values = {1, 2, 3};
    System.out.println("values = " + values);

}

다음과 같이 기본형 변수 하나와, 참조형 변수 하나에 값을 할당하고, 출력해보았다. 

 

 

 

기본형은 대입했던 숫자가 그대로 출력되었고, 참조형은 알 수 없는 값이 출력되었다.

알 수 없는 값이란, 해당 변수의 주소값이고 참조형은 그 주소값을 바라보고 있다는 것을 확인할 수 있다.

 

System.out.println("values[0] = " + values[0]);
System.out.println("values[1] = " + values[1]);
System.out.println("values[2] = " + values[2]);

 

배열의 값에 접근하고 싶으면 다음과 같이 해당 변수의 주소값 안에 있는 값의 위치를 출력해주어야 한다.

 

 

여기서는 배열이라는 것에 집중하기 보다,

참조형은 주소값을 가지고 있고 실제 값에 접근한다는 것에 초점을 맞추는게 좋다.

 

 

Call By Value와 Call By Reference

기본형과 참조형이 나올때, 자주 언급되는것이 바로 call by value, call by reference이다.

결국 실제값을 사용하는지, 실제값의 주소값을 사용하는지만 제대로 알고 있으면 된다.

 

Call By Value

메서드를 호출하는 변수와, 호출 당하는 파라미터는 복사된 서로 다른 변수이다.

기본형 자체가 사용할 값을 직접 저장하고 있기 때문에 그 값 자체를 넘기는 것 이다.

값만 복사해서 넘기기때문에, 메소드 안에서 어떤 일이 벌어져도 파라미터로 보낸 변수가 바뀌는 일은 없다.

 

public static void main(String[] args) {
    int a = 10;
    int b = a;
    System.out.println("a = " + a);
    System.out.println("b = " + b);

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

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

 

 

int형 변수 a에는 10을 할당해주고 b에는 a를 넣어준다.

두 변수 모두 10이라는 값이 들어있다.

 

 

a의 값을 20으로 변경하고, a와 b를 출력해주면 a의 값만 변한다.

b의 값을 30으로 변경하고, 역시 a와 b를 출력해주면 b의 값만 변하는 것을 알 수 있다.

 

Call By Reference

메소드에서 호출하는 매개변수는 그 주소값을 파라미터로 넘긴다.

그렇기 때문에 호출하는 매개변수와 호출당하는 파라미터는 동일한 주소값을 가진다.

메서드에 접근해서 수정하면, 같은 주소값을 바라보고 있기 때문에 매개변수의 값도 수정된다.

참조형 변수를 파라미터로 보내면 해당 참조형 변수의 값을 변경할 수 있다.

 

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

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

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

 

Data 타입의 변수 dataA와 dataB가 있다.

먼저 dataA를 생성하고, dataB에는 dataA를 넣어준다.

이 경우 dataA와 dataB는 모두 같은 참조값을 가지고 있다.

 

 

dataA의 값을 변경해주고 dataA와 dataB를 출력하면 두 변수의 값이 모두 변한 것을 확인할 수 있다.

마찬가지로, dataB의 값을 변경해주고 dataA와 dataB를 출력해주면 두 변수의 값이 모두 변해있다.

 

 

자바의 대원칙

자바는 항상 변수의 값을 복사해서 대입한다.

기본형과 참조형에서 헷갈리는 부분은 바로 메소드를 호출할때다.

이때, 이 원칙을 생각하면 쉽게 접근할 수 있다.

 

Call by Value / Call by Referenc는 해당 이야기를 하는 것 이다.

"자바는 항상 변수의 값을 복사해서 대입한다" 라는 말을 기억하고 있으면 쉽게 이해할 수 있다.

값이 실제값인지, 주소값인지만 생각해보자!