IT's Jenna

섹션 2. 기본형과 참조형 본문

Study/김영한의 실전 자바 - 기본편

섹션 2. 기본형과 참조형

developer Jenna 2024. 2. 4. 16:54

1. 변수의 데이터 타입

1. 기본형 (Primitive Type)

  • 사용하는 값을 변수에 직접 넣음
  • int, long, double, boolean
  • 직접 연산 가능

2. 참조형 (Reference Type)

  • 객체가 저장된 메모리 위치를 가리키는 참조값(주소값)을 넣음
  • 객체(클래스), 배열
  • 직접 연산 불가, 객체의 기본형 멤버 변수에 접근하여 연산은 가능
Student s1 = new Student();
s1.grade = 100;
Student s2 = new Student();
s2.grade = 90;
int sum = s1.grade + s2.grade; //연산 가능

 

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

package ref;

public class VarChange1 {

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

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

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

    }
}

 

기본형은 값을 직접 대입하기 때문에 이미 대입한 값은 이전 값 과는 상관이 없다

package ref;

public class Data {
    int value;
}

 

value라는 멤버 변수를 하나 가지는 Data 클래스 생성

package ref;

public class VarChange2 {

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

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

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

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

 

DataA는 주소값 x001, DataB 역시 주소값 x001을 대입함

인스턴스가 복사되는 것이 아니고 동일한 인스턴스를 찾아가는 주소값만 하나 더 생긴 것일 뿐이다!

 

2. 기본형과 참조형에서의 메서드 호출

package ref;

public class MethodChange1 {

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

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

 

x에 a값을 대입하더라도 a값은 변하지 않는다.

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); //10
        System.out.println("dataA=" + dataA);
        changeReference(dataA);
        System.out.println("메서드 호출 후: dataA.value = " + dataA.value); //20
    }

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

 

changeReference에 보내지는 매개변수는 dataA의 주소값이므로 dataX가 바라보는 인스턴스도 dataA와 동일하다.

결국 value값은 변경된다.

 

3. 참조형과 메서드 호출 - 활용

package ref;

public class Method1 {

    public static void main(String[] args) {
        Student student1 = new Student(); //x001
        initStudent(student1, "학생1", 15, 90);

        Student student2 = new Student(); //x002
        initStudent(student2, "학생2", 16, 80);

        printStudent(student1);
        printStudent(student2);
    }

    static void initStudent(Student student, String name, int age, int grade) {
        student.name = name;
        student.age = age;
        student.grade = grade;
    }

    static void printStudent(Student student) {
        System.out.println("이름:" + student.name + " 나이:" + student.age + " 성적:" + student.grade);
    }
}

 

참조형의 메서드를 통해서 멤버 변수를 변경할 수 있다는 점을 활용하여 인스턴스를 생성하고 초기화하는 과정을 단순화할 수 있다.

- initStudent 함수는 만들어진 인스턴스의 멤버 변수를 초기화 한다

- printStudent는 각 인스턴스의 초기화된 내용을 프린트한다

 

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); //10
        System.out.println("dataA=" + dataA);
        changeReference(dataA);
        System.out.println("메서드 호출 후: dataA.value = " + dataA.value); //20
    }

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

 

인스턴스를 생성하고 초기화하는 과정을 모두 합쳐서 더욱 단순하게 만들 수 있다.

 

4. 초기화

public class InitData {
    int value1; //초기화 하지 않음
    int value2 = 10;//10으로 초기화
}

 

멤버변수에 초기화하지 않더라도 기본값으로 들어간다.

  • 숫자 : 0
  • boolean : false
  • 참조형 : null

5. 가비지 컬렉션

package ref;

public class NullMain1 {

    public static void main(String[] args) {
        Data data = null;
        System.out.println("1. data = " + data);
        data = new Data();
        System.out.println("2. data = " + data);
        data = null;
        System.out.println("3. data = " + data);
    }
}

객체를 생성했다가 그 주소값을 잃어버리면 해당 객체에 다시 접근할 방법이 없다. 이 객체는 메모리에 떠다니며 용량만 차지하게 된다.

자바는 이렇게 아무도 참조하지 않는 인스턴스가 있으면 자동으로 메모리에서 제거해 주는 GC(가비지 컬렉션)이 있다.

 

6. NullPointerException

package ref;

public class NullMain2 {
    public static void main(String[] args) {
        Data data = null;
        data.value = 10; //NullPointerException 예외 발생
        System.out.println("data = " + data.value);
    }
}

 

주소값이 없으면 NullPointerException 에러 발생

'Study > 김영한의 실전 자바 - 기본편' 카테고리의 다른 글

섹션 1. 클래스와 데이터  (0) 2024.01.15
Comments