[Java] 기본형 vs 참조형 2️⃣ - 변수 대입

코드 속의 "진돌"·2024년 1월 23일
1
post-thumbnail

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


자바에서 변수에 값을 대입하는 것은 변수에 들어 있는 값을 복사해서 대입하는 것이다.

기본형, 참조형 모두 항상 변수에 있는 값을 복사해서 대입한다. 기본형이면 변수에 들어 있는 실제 사용하는 값을 복사해서 대입하고, 참조형이면 변수에 들어 있는 참조값을 복사해서 대입한다.


✏️ 기본형 대입

int a = 10;
int b = a;

✏️ 참조형 대입

Student s1 = new Student();
Student s2 = s1;

기본형은 변수에 값을 대입하더라도 실제 사용하는 값이 변수에 바로 들어있기 때문에 해당 값만 복사해서 대입한다고 생각하면 된다. 그런데 참조형의 경우, 실제 사용하는 객체가 아니라 객체의 위치를 가리키는 참조값만 복사된다.




✅ 기본형과 변수 대입


✏️ VarChange1

package ref;

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 변경
    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);
  }
}



✏️ 실행 결과



✏️ 실행 결과 해석

1️⃣ int a = 10;


2️⃣ int b = a;

✏️ 실행 결과

a = 10
b = 10

변수의 대입은 변수에 들어있는 값을 복사해서 대입한다. 여기서는 변수 a에 들어있는 값 10을 복사해서 변수 b에 대입한다. 변수 a 자체를 b에 대입하는 것이 아니다.


3️⃣ a = 20;

✏️ 실행 결과

a = 20
b = 10

변수 a에 값 20을 대입했다. 따라서 변수 a의 값이 10에서 20으로 변경되었다. 변수 b에는 아무런 영향을 주지 않는다.


4️⃣ b = 30;

✏️ 실행 결과

a = 20
b = 30

변수 b에 값 30을 대입했다. 변수 b의 값이 10에서 30으로 변경되었다. 변수 a에는 아무런 영향을 주지 않는다.



✏️ 최종 결과

여기서 핵심은 int b = a;라고 했을 때 변수에 들어있는 값을 복사해서 전달한다는 점이다. 따라서 a = 20, b = 30이라고 했을 때 각각 본인의 값만 변경되는 것을 확인할 수 있다.




✅ 참조형과 변수 대입


Data 클래스를 만들자. 이 클래스는 int value라는 멤버 변수를 가진다.

✏️ Data

package ref;

public class Data {
  int value;
}

✏️ VarChange2

package ref;

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

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

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



✏️ 실행 결과



✏️ 실행 결과 해석

dataA 변수는 Data 클래스를 통해서 만들었기 때문에 참조형이다. 이 변수는 Data형 객체의 참조값을 저장한다.

Data 객체를 생성하고, 참조값을 dataA에 저장한다. 그리고 객체의 value 변수에 값 10을 저장했다.

✏️ 실행 코드

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 참조값 : ref.Data@30f39991
dataB 참조값 : ref.Data@30f39991
dataA.value : 10
dataB.value : 10

변수의 대입은 변수에 들어있는 값을 복사해서 대입한다. 변수 dataA에는 참조값 x001이 들어있다. 여기서는 변수 dataA에 들어있는 참조값 x001을 복사해서 dataB에 대입한다. 참고로 변수 dataA가 가리키는 인스턴스를 복사하는 것이 아니라, 변수에 들어있는 참조값만 복사해서 전달한다.

이제 dataAdataB에 들어있는 참조값은 같다. 따라서 둘 다 같은 x001 Data 인스턴스를 가리킨다.


✏️ 실행 코드

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

✏️ 출력 결과

dataA.value = 20
dataB.value = 20

dataA.value = 20 코드를 실행하면 dataA가 가리키는 x001 인스턴스의 value값을 10에서 20으로 변경한다. 그런데 dataAdataB는 같은 x001 인스턴스를 참조하기 때문에 dataA.valuedataB.value는 둘 다 같은 값인 20을 출력한다.


✏️ 실행 코드

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

✏️ 출력 결과

dataA.value = 30
dataB.value = 30

dataB.value = 30 코드를 실행하면 dataB가 가리키는 x001 인스턴스의 value값을 20에서 30으로 변경한다. 그런데 dataAdataB는 같은 x001 인스턴스를 참조하기 때문에 dataA.valuedataB.value는 같은 값인 30을 출력한다.

여기서 핵심은 Data dataB = dataA라고 했을 때 변수에 들어있는 값을 복사해서 사용한다는 점이다. 그런데 그 값이 참조값이다. 따라서 dataAdataB는 같은 참조값을 가지게 되고, 두 변수는 같은 객체 인스턴스를 참조하게 된다.

💡 출처

https://www.inflearn.com/course/김영한의-실전-자바-기본편

profile
매일 성장하는 주니어 개발자의 기록📝

0개의 댓글