[Java 기본] 19. 기본형과 참조형

자바에서 변수는 크게 기본형(Primitive Type)참조형(Reference Type)으로 나눌 수 있다.

 

먼저 기본형(Primitive Type)값 자체를 저장하는 타입으로 메모리에 바로 값이 들어간다.

ex) int, long, double, boolean

stack에 값이 바로 저장된다.

'=='를 이용해 값을 비교할 수 있다.

기본형은 소문자로 시작하며 자바가 기본으로 제공하는 데이터 타입이다.

 

int a = 10, b = 20;

int sum = a + b;

기본형은 들어있는 값을 그대로 계산할 수 있다.

 

 

참조형(Reference Type)주소(참조값)를 저장하는 타입으로 실제 값은 힙(Heap) 메모리에 있고, 변수에는 그 값의 주소만 저장된다.

ex) Student student1 객체, int [ ] students 배열, String, 인터페이스 등

stack에는 주소값이 저장되고, 그 주소가 힙(Heap)에 있는 데이터를 가리킨다. 

'=='를 사용하면 주소(참조값)를 비교하고, 값 비교는. equals()를 사용한다.

참조형은 대문자(String, Student)로 시작하고 개발자는 클래스를 통해 새로운 데이터 타입을 정의할 수 있다.

 

Student s1 = new Student();

Student s2 = new Student();

s1+s2 //참조값은 연산 불가능하므로 오류 발생

 

s1.grade = 100;

s2.grade = 90;

int sum = s1.grade + s2.grade; //dot을 통해 기본형인 멤버변수로 접근한 경우에는 연산 가능

주소지를 통해 메모리에 생성된 값을 찾으면 계산할 수 있다. 참조값만 가지고는 연산 불가능하다.

 

 

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

 

기본형은 변수에 들어있는 실제 사용하는 을, 참조형은 변수에 들어있는 참조값복사 대입한다.

 

예를 들어, 

 

public class Data {

    int value;

}

 

public class VarCharge2 {

    public static void main(String[] args) {

        Data dataA = new Data();

        dataA.value = 10;

        Data dataB = dataA;  //dataB는 dataA와 같은 주소를 가리키게 됨

        System.out.println(dataA.value);

        System.out.println(dataB.value);

 

출력 결과 : 

10

10

 

 

 

메서드 호출과 변수 (기본형, 참조형)

 

기본형과 메서드 호출

메서드로 기본형 데이터를 전달하면 복사되어 전달되는데, 메서드 내부에서 매개변수(파라미터)의 값을 변경하더라도 호출자변수 값에는 변화가 없다. 

 

ex)

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의 값엔 영향을 주지 않는다.

//x값만 10에서 20으로 변경되고 메서드가 종료되면 매개변수 x는 삭제된다.

 

 

참조형과 메서드 호출

메서드로 참조형 데이터를 전달하면, 참조값이 복사되어 전달된다. 따라서 메서드 내부에서 매개변수(파라미터)로 전달된 객체의 멤버 변수를 변경하면, 호출자객체변경된다.

 

ex)

public static void main(String[] args) {

    Data dataA = new Data();

    dataA.value = 10;

    System.out.println("메서드 호출 전: dataA.value = " + dataA.value);

    changePrimitive(dataA); //매개변수에 dataA의 주소를 복사해서 전달

    System.out.println("메서드 호출 후: dataA.value = " + dataA.value);

}

static void changeReference(Data dataX) {

    dataX.value = 20;

}

 

출력 결과:

메서드 호출 전: dataA.value = 10

메서드 호출 후: dataA.value = 20

 

 

참조형과 메서드 활용

 

public class Student {

    String name;

    int age;

    int grade;

}

 

public static void main(String[] args) {

     Student student1 = createStudent(student1, "박명수", 17, 70);

     Student student2 = createStudent(student2, "최양락", 16, 85);

 

     printStudent(student1);

     printStudent(student2);

}

 

static void createStudent(Student student, String name, int age, int grade) {

     Student student = new Student();

     student.name = name;

     student.age = age;

     student.grade = grade;

     return student; //메서드 안에서 만든 객체의 주소값 리턴

}

 

static void printStudent(Student student1) {

    System.out.println("이름:" + student1.name + " 나이:" + student1.age + " 성적:" + student1.grade);

}

 

 

멤버 변수 vs 지역 변수

 

멤버 변수(필드) : 클래스 내에서 선언된 변수

인스턴스를 생성하면 자동으로 초기화되고 개발자가 직접 지정할 수도 있다.

int = 0, boolean = false, 참조형 = null

 

지역 변수 : 메서드 내에서 선언된 변수로 매개변수도 지역변수의 한 종류이다.

메서드가 종료되면 지역 변수도 삭제된다.

지역 변수는 항상 개발자가 직접 초기화해야 오류가 발생하지 않는다.

'백엔드 > Java' 카테고리의 다른 글

[Java 기본] 20. null 값  (0) 2025.08.30
[Java 기본] 18. 클래스와 객체  (3) 2025.08.18
[Java 입문] 17. 메서드  (1) 2025.08.06
[Java 입문] 16. 2차원 배열, for-each문  (4) 2025.08.05
[Java 입문] 15. 배열  (0) 2025.08.05