본 게시글은 김영한 강사님의 [김영한의 실전 자바 - 기본편]을 수강하며 작성한 글입니다.
01. 기본형 vs 참조형
변수의 데이터 타입을 가장 크게 보면 기본형과 참조형으로 분류할 수 있다.
기본형(Primitive Type)
변수에 사용할 값을 직접 넣을 수 있는 데이터 타입을 말한다.
- ex.
int
,long
,double
,boolean
- 실제 사용하는 값을 변수에 담을 수 있다.
- 들어있는 값을 그대로 계산에 사용할 수 있다.
int a = 10, b = 20;
int sum = a + b;
참조형(Reference Type)
데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입을 말한다.
- ex.
Student student1
,int[] students
- 실제 사용하는 값을 변수에 담는 것이 아니다. 이름 그대로 실제 객체의 위치(참조, 주소)를 저장한다.
- 객체 또는 배열에 사용된다.
- 객체는
.(dot)
을 통해서 메모리 상에 생성된 객체를 찾아가야 사용할 수 있다. - 배열은
[]
를 통해서 메모리 상에 생성된 배열을 찾아가야 사용할 수 있다.
- 객체는
- 들어있는 참조값을 그대로 계산에 사용할 수 없다. 주소지에 가야 실체가 존재한다.
Student s1 = new Student();
Student s2 = new Student();
s1 + s2 // 오류 발생
다음과 같이 멤버 변수에 접근한 경우에는 연산이 가능하다.
Student s1 = new Student();
s1.grade = 100;
Student s2 = new Student();
s2.grade = 90;
int sum = s1.grade + s2.grade; //연산 가능
💡 쉽게 이해하기
기본형을 제외한 나머지는 모두 참조형이다.
기본형은 소문자로 시작한다.
-int
,long
,double
,boolean
모두 소문자로 시작한다.
- 기본형은 자바가 기본으로 제공하는 데이터 타입이다. 이러한 기본형은 개발자가 새로 정의할 수 없다.
클래스는 대문자로 시작한다.
-Student
도 대문자로 시작한다.
- 클래스는 모두 참조형이다. 개발자는 참조형인 클래스만 직접 정의할 수 있다. </aside>
💡 String
자바에서 String은 사실 클래스이다. 따라서 참조형이다. 그런데 기본형처럼 문자 값을 바로 대입할 수 있다.
문자는 매우 자주 다루기 때문에 자바에서 특별하게 편의 기능을 제공하기 때문이다.
변수 대입
대원칙: 자바는 항상 변수의 값을 복사해서 대입한다.
자바에서 변수에 값을 대입하는 것은 변수에 들어 있는 값을 복사해서 대입하는 것이다.
기본형, 참조형 모두 항상 변수에 있는 값을 복사해서 대입한다. 기본형이면 변수에 들어 있는 실제 사용하는 값을 복사해서 대입하고, 참조형이면 변수에 들어 있는 참조값을 복사해서 대입한다.
- 기본형 대입
변수에 값을 대입하더라도 실제 사용하는 값이 변수에 바로 들어있기 때문에 해당 값만 복사해서 대입한다.int a = 10; int b = a;
- 참조형 대입
실제 사용하는 객체가 아니라 객체의 위치를 가리키는 참조값만 복사된다.Student s1 = new Student(); Student s2 = s1;
메서드 호출
대원칙: 자바는 항상 변수의 값을 복사해서 대입한다.
메서드를 호출할 때 사용하는 매개변수(파라미터)도 결국 변수일 뿐이다. 따라서 메서드를 호출할 때 매개변수에 값을 전달하는 것도 값을 복사해서 전달한다.
자바에서 메서드의 매개변수(파라미터)는 항상 값에 의해 전달된다. 그러나 이 값이 실제 값이냐, 참조(메모리 주소)값이냐에 따라 동작이 달라진다.
- 기본형 메서드 호출
- 메서드로 기본형 데이터를 전달하면, 해당 값이 복사되어 전달된다.
- 메서드 내부에서 매개변수(파라미터)로 전달된 값을 변경해도, 호출자의 변수 값에는 영향이 없다.
- 참조형 메서드 호출
- 메서드로 참조형 데이터를 전달하면, 참조값이 복사되어 전달된다.
- 메서드 내부에서 매개변수(파라미터)로 전달된 객체의 멤버 변수를 변경하면, 호출자의 객체도 변경된다.
02. 변수와 초기화
변수의 종류
- 멤버 변수(필드): 클래스에 선언
public class Student {
String name;
int age;
int grade;
}
name
, age
, grade
는 멤버 변수이다.
- 지역 변수: 메서드에 선언, 매개변수도 지역 변수의 한 종류이다.
public class ClassStart3 {
public static void main(String[] args) {
Student student1;
student1 = new Student();
Student student2 = new Student();
}
}
student1
, student2
는 지역 변수이다.
변수의 값 초기화
- 멤버 변수: 자동 초기화
- 인스턴스의 멤버 변수는 인스턴스를 생성할 때 자동으로 초기화된다.
- 숫자(int)=
0
- boolean =
false
- 참조형 =
null
(null 값은 참조할 대상이 없다는 뜻으로 사용된다.)
- 숫자(int)=
- 개발자가 초기값을 직접 지정할 수 있다.
- 인스턴스의 멤버 변수는 인스턴스를 생성할 때 자동으로 초기화된다.
- 지역 변수: 수동 초기화
- 지역 변수는 항상 직접 초기화해야 한다.
03. null
참조형 변수에는 항상 객체가 있는 위치를 가리키는 참조값이 들어간다. 그런데 참조형 변수에서 아직 가리키는 대상이 없다면 null
이라는 특별한 값을 넣어둘 수 있다. null은 값이 존재하지 않는, 없다는 뜻이다.
null 값 할당
public class NullMain1 {
public static void main(String[] args) {
Data data = null;
System.out.println("1. data = " + data); // null
data = new Data();
System.out.println("2. data = " + data); // ref.Data@x001
data = null;
System.out.println("3. data = " + data); // null
}
}
💡 GC(Garbage Collection)
data에 null을 할당했다. 따라서 앞서 생성한 Data 인스턴스를 더는 아무도 참조하지 않는다. 아무도 참조하지 않게 되면 해당 인스턴스에 다시 접근할 방법이 없다. 이렇게 아무도 참조하지 않는 인스턴스는 사용되지 않고 메모리 용량만 차지할 뿐이다.
C와 같은 과거 프로그래밍 언어는 개발자가 직접 명령어를 사용해서 인스턴스를 메모리에서 제거해야 했다. 만약 실수로 인스턴스 삭제를 누락하면 메모리에 사용하지 않는 객체가 가득해져서 메모리 부족 오류가 발생하게 된다.
자바는 이런 과정을 자동으로 처리해준다. 아무도 참조하지 않는 인스턴스가 있으면 JVM의 GC(가비지 컬렉션)가 더이상 사용하지 않는 인스턴스라 판단하고 해당 인스턴스를 자동으로 메모리에서 제거해준다.
객체는 해당 객체를 참조하는 곳이 있으면, JVM이 종료할 때 까지 계속 생존한다. 그런데 중간에 해당 객체를 참조하는 곳이 모두 사라지면 그때 JVM은 필요 없는 객체로 판단다고 GC(가비지 컬렉션)를 사용해서 제거한다.
04. NullPointerException
참조값 없이 객체를 찾아가면 NullPointerException
이라는 예외가 발생한다.
NullPointerException은 이름 그대로 null을 가리키다(Pointer)인데, 이때 발생하는 예외(Exception)다. null은 없다는 뜻이므로 결국 주소가 없는 곳을 찾아갈 때 발생하는 예외이다.
객체를 참조할 때는 .(dot)을 사용한다. 그런데 참조값이 null이라면 값이 없다는 뜻이므로, 찾아갈 수 있는 객체(인스턴스)가 없다. NullPointerException은 이처럼 null에 .(dot)을 찍었을 때 발생한다.
지역 변수와 Null
public class NullMain2 {
public static void main(String[] args) {
Data data = null;
data.value = 10; // NullPointerException 예외 발생
System.out.println("data = " + data.value);
}
}
멤버 변수와 null
지역 변수의 경우에는 null 문제를 파악하는 것이 어렵지 않다. 하지만 다음과 같이 멤버 변수가 null인 경우에는 주의가 필요하다.
public class Data {
int value;
}
public class BigData {
Data data;
int count;
}
public class NullMain3 {
public static void main(String[] args) {
BigData bigData = new BigData();
System.out.println("bigData.count=" + bigData.count); // 0
System.out.println("bigData.data=" + bigData.data); // null
// NullPointerException 예외 발생
System.out.println("bigData.data.value=" + bigData.data.value);
}
}
NullPointerException
이 발생하면 null값에 .(dot)
을 찍은 것이다.
'Courses > Java' 카테고리의 다른 글
[김영한의 실전 자바 - 기본편] 3. 객체 지향 프로그래밍 (0) | 2024.05.05 |
---|---|
[김영한의 실전 자바 - 기본편] 1. 클래스와 데이터 (0) | 2024.03.21 |