Java

기본형과 참조형

공부처음하는사람 2024. 5. 7. 19:17

기본형과 참조형에 대해 공부했다.

변수의 데이터 타입을 크게 본다면 기본형과 참조형 두가지로 분류할 수 있다.

기본형은 사용하는 값을 변수에 직접 넣는 방식. (int, long, double, boolean)

참조형은 객체가 저장된 메모리의 위치 (참조값)을 넣는 방식 (Student student1, int[ ] students), 객체 또는 배열에 사용됨

 

기본형 vs 참조형

  • 기본형은 숫자 10, 20과 같이 실제 사용하는 값을 변수에 담을 수 있다. 그리고 그 값을 바로 사용할 수 있다.
  • 참조형은 실제 사용하는 값을 담지 않는다. 이름 그대로 객체의 위치 (참조, 주소)를 담는다. 참조형에는 객체와 배열이 있다.
    (객체는 . (dot)을 사용해 객체로 접근해야 사용이 가능하고, 배열은 [ ]를 통해 접근하여 사용이 가능하다.

 

기본형 vs 참조형 - 계산

  • 기본형은 연산이 가능하다.
  • 참조형은 연산이 불가능하다. (. 을 통해 객체의 멤버변수에 접근한 경우엔 연산이 가능하다.)

 

기본형은 소문자로 시작한다. (int, long, double, boolean)
참조형은 대문자로 시작한다. (Student, String)

 

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

 

기본형은 해당 값을 읽고 복사해서 대입한다.
참조형은 참조값만 복사해서 대입한다.

 

참조형의 변수 대입

package ref;

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

        System.out.println("data A 참조값: " + dataA);
        System.out.println("data B 참조값: " + dataB);
        System.out.println("dataA.value: " + dataA.value);
        System.out.println("dataB.value: " + dataB.value);

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

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

 

출력 결과는 10, 10 / 20, 20 / 30, 30 이 나온다.
10은 당연히 그렇다 치고, 20, 30은 왜 나왔을까?

 

dataA.value = 20 코드를 실행하면 dataA가 가리키는 참조값 (x001) 인스턴스의 value값을 10에서 20으로 변경시킨다.

그런데 dataA와 dataB는 같은 x001 인스턴스를 참조하기 때문에 둘의 값은 20으로 동일한 값이 출력되는 것이다.

 

기본형과 메서드 호출

package ref;

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

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

 

위 코드를 실행하면 전 후 모두 10이 나온다. 그 이유는 무엇일까?

메서드를 호출할 때 매개변수 x에 변수 a값을 복사해 전달한다.

int x = a와 같게 된 것이다. 그러므로 현재 a, x = 10이다.

그 이후 메서드 안에서 x = 20이 실행된다. 그러면 x의 값은 20이다.

a의 값은 10으로 유지된다. (값을 복사했기 때문에)

메서드 종료 후 a는 10이 출력되고, 메서드가 종료되면 매개변수 x는 제거된다.

 

 

 

참조형과 메서드 호출

package ref;

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

    public static void changeReference(Data dataX) {
        dataX.value = 20;
    }
}

 

이 부분은 처음부터 이해해서 그림을 안그려도 될 것 같다.

둘은 같은 인스턴스를 참조하기 때문에 둘의 값은 항상 같은 값이 될 것이다.

 


 

코틀린으로 코딩을 했을 땐 이런 부분을 전혀 모르고 있었는데, 새로운 섹션을 들을 때 마다 모르는 것 투성이이다.

어렵기도 하고 재밌기도 하다

'Java' 카테고리의 다른 글

생성자  (0) 2024.05.15
객체 지향 프로그래밍  (1) 2024.05.08
클래스 - 배열  (1) 2024.05.07
클래스, 객체, 인스턴스  (0) 2024.05.07
삼항 연산자  (1) 2024.04.25