기본형과 참조형

가오리·2024년 5월 31일
0
post-thumbnail

'김영한의 실전 자바 - 기본편' 강의를 들으면서 복습할만한 내용을 정리하였다.

2. 기본형과 참조형

2.1 기본형 vs 참조형

자바에서 참조형을 제대로 이해하는 것은 정말 중요하다.

사용하는 값을 변수에 직접 넣을 수 있는 기본형, 객체가 지정된 메모리의 위치를 가리키는 참조값을 넣을 수 있는 참조형으로 분류할 수 있다.

  • 기본형(Primitive Type) : int, long, double, boolean 처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입을 기본형이라 한다.

  • 참조형(Reference Type) : Student student, int[] students 와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입을 참조형이라 한다. 참조형은 객체 또는 배열에 사용된다.

쉽게 이야기해서 기본형 변수에는 직접 사용할 수 있는 값이 들어있지만 참조형 변수에는 위치(참조값)가 들어가 있다. 참조형 변수를 통해서 뭔가 하려면 결국 참조값을 통해 해당 위치로 이동해야 한다.

쉽게 이해하는 팁

기본형을 제외한 나머지는 모두 참조형이다.

  • 기본형은 소문자로 시작한다. int, long, double, boolean 모두 소문자로 시작한다.
    • 기본형은 자바가 기본으로 제공하는 데이터 타입이다. 이러한 기본형은 개발자가 새로 정의할 수 없다. 개발자는 참조형인 클래스만 직접 정의할 수 있다.
  • 클래스는 대문자로 시작한다. Student
    • 클래스는 모두 참조형이다.

참고 - String

자바에서 String 은 특별하다. String 은 사실은 클래스다. 따라서 참조형이다. 그런데 기본형처럼 문자 값을 바로 대입할 수 있다. 문자는 매우 자주 다루기 때문에 자바에서 특별하게 편의 기능을 제공한다.

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

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

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

참조형의 경우 실제 사용하는 객체가 아니라 객체의 위치를 가리키는 참조값만 복사된다. 쉽게 이야기해서 실제 건물이 복사가 되는 것이 아니라 건물의 위치인 주소만 복사되는 것이다. 따라서 같은 건물을 찾아갈 수 있는 방법이 하나 늘어날 뿐이다.

2.2 참조형과 메서드 호출

package ref;
public class Method2 {
 		public static void main(String[] args) {
 		Student student1 = createStudent("학생1", 15, 90);
 		Student student2 = createStudent("학생2", 16, 80);
 		printStudent(student1);
 		printStudent(student2);
 	}
    
 	static Student createStudent(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);
 	}
}

메서드 내부에서 인스턴스를 생성한 후에 참조값을 메서드 외부로 반환했다. 이 참조값만 있으면 해당 인스턴스에 접근할 수 있다. 여기서는 student1 에 참조값을 보관하고 사용한다.

참조형은 메서드를 호출할 때 참조값을 전달한다. 따라서 메서드 내부에서 전달된 참조값을 통해 객체의 값을 변경하거나, 값을 읽어서 사용할 수 있다.

2.3 null

참조형 변수에는 항상 객체가 있는 위치를 가리키는 참조값이 들어간다. 그런데 아직 가리키는 대상이 없거나, 가리키는 대상을 나중에 입력하고 싶다면 어떻게 해야할까?

참조형 변수에는 아직 가리키는 대상이 없다면 null 이라는 특별한 값을 넣어둘 수 있다. null은 값이 존재하지 않는, 없다는 뜻이다.

멤버 변수에서의 참조형의 값 초기화는 참조형 = null 로 자동 초기화해준다.

GC - 아무도 참조하지 않는 인스턴스의 최후

datanull을 할당했다. 따라서 앞서 생성한 x001 Data 인스턴스를 더는 아무도 참조하지 않는다. 이렇게 아무도 참조하지 않게 되면 x001이라는 참조값을 다시 구할 방법이 없다. 따라서 해당 인스턴스에 다시 접근할 방법이 없다.

이렇게 아무도 참조하지 않는 인스턴스는 사용되지 않고 메모리 용량만 차지할 뿐이다.

C와 같은 과거 프로그래밍 언어는 개발자가 직접 명령어를 사용해서 인스턴스를 메모리에서 제거해야 했다. 만약 실수로 인스턴스 삭제를 누락하면 메모리에 사용하지 않는 객체가 가득해져서 메모리 부족 오류가 발생하게 된다.

자바는 이런 과정을 자동으로 처리해준다. 아무도 참조하지 않는 인스턴스가 있으면 JVMGC (가비지 컬렉션)가 더 이상 사용하지 않는 인스턴스라 판단하고 해당 인스턴스를 자동으로 메모리에서 제거해준다.

객체는 해당 객체를 참조하는 곳이 있으면, JVM 이 종료할 때 까지 계속 생존한다. 그런데 중간에 해당 객체를 참조하는 곳이 모두 사라지면 그때 JVM은 필요 없는 객체로 판단하고 GC를 사용해서 제거한다.

2.4 NullPointerException

만약 참조값이 없이 객체를 찾아가면 어떤 문제가 발생할까?

이 경우 NullPointerException 이라는 예외가 발생하는데, 개발자를 가장 많이 괴롭히는 예외이다.

NullPointerException은 이름 그래도 null 을 가리키나(Pointer)인데, 이때 발생하는 예외(Exception)다.

null은 없다는 뜻이므로 결국 주소가 없는 곳을 찾아갈 때 발생하는 예외이다.

객체를 참조할떄는.(dot)을 사용한다. 이렇게 하면 참조값을 사용해서 해당 객체를 찾아갈 수 있다. 그런데 참조값이 null 이라면 값이 없다는 뜻이므로, 찾아갈 수 있는 객체(인스턴스)가 없다. NullPointerException 은 이처럼 null.(dot)을 찍었을 때 발생한다.

NullPointerException이 발생하면 null 값에 . (dot)을 찍었따고 생각하면 문제를 쉽게 찾을 수 있다.

2.5 기본형과 참조형 정리

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

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

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

기본형이든 참조형이든 변수의 값을 대입하는 방식은 같다. 하지만 기본형과 참조형에 따라 동작하는 방식이 달라진다.

기본형 vs 참조형 - 기본

  • 자바의 데이터 타입을 가장 크게 보면 기본형과 참조형으로 나눌 수 있다.

  • 기본형을 제외한 나머지 변수는 모두 참조형이다. 클래스와 배열을 다루는 변수는, 참조형이다.

  • 기본형 변수는 값을 직접 저장하지만, 참조형 변수는 참조(주소)를 저장한다.

  • 기본형 변수는 산술 연산을 수행할 수 있지만, 참조형 변수는 산술 연산을 수행할 수 없다.

  • 기본형 변수는 null 을 할당할 수 없지만, 참조형 변수는 null을 할당할 수 있다.

기본형 vs 참조형 - 대입

  • 기본형과 참조형 모두 대입시 변수 안에 있는 값을 읽고 복사해서 전달한다.

  • 기본형은 사용하는 값을 복사해서 전달하고, 참조형은 참조값을 복사해서 전달한다! 이것이 중요하다. 실제 인스터스가 복사되는 것이 아니다. 인스턴스를 가리키는 참조값을 복사해서 전달하는 것이다! 따라서 하나의 인스턴스를 여러곳에서 참조할 수 있다.

  • 헷갈리면 그냥 변수 안에 들어간 값을 떠올려보자. 기본형은 사용하는 값이, 참조형은 참조값이 들어있다! 변수에 어떤 값이 들어있든간에 그 값을 그대로 복사해서 전달한다.

기본형 vs 참조형 - 메서드 호출

  • 메서드 호출시 기본형은 메서드 내부에서 매개변수(파라미터)의 값을 변경해도 호출자의 변수 값에는 영향이 없다.

  • 메서드 호출시 참조형은 메서드 내부에서 매개변수(파라미터)로 전달된 객체의 멤버 변수를 번경하면, 호출자의 객체도 변경된다.

profile
가오리의 개발 이야기

0개의 댓글