변수의 초기화란
변수의 선언으로 할당된 공간에 처음으로 값을 저장하는 것을 의미한다.
변수의 초기화를 크게 분류하면 3가지의 방법이 있다.
- 자동초기화
- 간단초기화 ( =명시적초기화)
- 복잡초기화
각각에 대해서 알아보자.
자동초기화
자동초기화 란, 사용자가 변수의 공간에 값을 저장하지 않았을 때 컴파일러에 의해 자동으로 값이 저장되는 것이다.
즉, 사용자가 변수를 수동으로 초기화 하지 않으면 자동으로 초기화 되는 것이다.
선언된 변수의 자료형 타입에 따라서 자동으로 초기화되는 값이 정해져 있다.(기본값 default value)
예를 들어서, int value; 이렇게 변수의 선언만 한 상태에서 변수에 값을 지정해주지 않는다면 변수 value의 공간에 int형 기본값인 0 이 저장된다.
다음 코드를 확인해 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class test_1 {
public static void main(String[] args) {
initiallization i = new initiallization();
System.out.println(i.iv); // 0 이 출력된다.
System.out.println(i.iv_2); // false 가 출력된다.
System.out.println(i.iv_3); // null 이 출력된다.
}
}
class initiallization {
int iv;
boolean iv_2;
String iv_3;
}
|
cs |
- 10행, 11행, 12행 에서 iv에 값을 저장하지 않았다.
- 4행, 5행, 6행 에서 각각의 iv를 출력하면 각각의 자료형 타입의 default value가 저장되어 있음을 알 수 있다.
하지만, 모든 변수들이 자동초기화가 되지는 않는다는 점을 기억해야한다.
지역변수는 자동초기화가 되지 않으므로 사용 전 반드시 수동으로 초기화를 해야한다.
따라서 초기화를 하지 않은 상태에서 지역변수를 사용하면 컴파일 에러가 발생한다.
반면에, 멤버변수(iv, cv)는 자동초기화가 되기 때문에 수동 초기화를 하지 않고도 변수의 사용이 가능하다.
간단초기화
간단초기화 란, 명시적 초기화라고도 불리며, 간단히 말해서 대입연산자 " = " 를 이용해서 변수의 공간에 직접 값을 저장하는 것이다.
가장 기본적인 변수의 초기화 방법이니 따로 예시는 적지는 않는다..
복잡초기화
복잡초기화 는 2개로 분류된다.
- 초기화 블럭 사용
- 생성자
우선 초기화 블럭에 대해서 알아본다면 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class test_1 {
public static void main(String[] args) {
initiallization i = new initiallization();
System.out.println(i.iv); // 3 이 출력된다.
System.out.println(initiallization.cv); // 10 이 출력된다.
}
}
class initiallization {
int iv;
static int cv;
{iv = 3;} // 인스턴스변수의 초기화 블럭
static{cv = 10;} // 스태틱 변수의 초기화 블럭
}
|
cs |
- 12행을 보면 인스턴스 변수의 초기화 블럭을 이용하여 인스턴스 변수를 3 으로 초기화 하였다.
- 13행을 보면 스태틱 변수의 초기화 블럭을 이용하여 스태틱 변수를 10으로 초기화 하였다.
- 4행, 5행의 출력 결과를 통해 정상적으로 초기화가 되었음을 확인할 수 있다.
초기화 블럭을 사용하여 멤버변수를 초기화 하는 방법은 위의 예시를 통해 확인할 수 있다.
인스턴스변수는 { } 블럭 안에서 변수를 초기화 하고,
스태틱 변수는 static { } 블럭 안에서 변수를 초기화 하면 된다.
생성자란, 객체의 인스턴스 변수를 초기화 할 때 사용한다.
생성자는 한마디로 인스턴스 초기화(iv초기화) 메서드인데, 생성자에 대해서는 다른 포스트를 참고하자. (생성자 중요개념)
생성자를 이용하여 초기화 하는 방법은 인스턴스 변수를 초기화 할 때만 사용할 수 있다.
따라서 스태틱 변수는 생성자를 통해서 초기화가 불가능하다.
왜냐하면 생성자라는 것도 일종의 메서드이고, 메서드 중에서도 인스턴스 메서드에 해당한다.
인스턴스 메서드에서 스태틱 멤버(cv, cm)를 사용할 수 없다는 것은 당연한 개념이다.
여기까지 복잡초기화에는 초기화블럭을 이용하는 방법과 생성자를 이용하는 방법이 있다는 것 까지 알아 보았다.
멤버 변수의 복잡 초기화 방법에 대해서 정리하자면,
인스턴스 변수는 (1)생성자를 이용하는 방법, (2)초기화블럭을 이용하는 방법 을 전부 사용할 수 있고,
스태틱 변수는 오직 초기화블럭을 이용하는 방법만을 사용할 수 있다.
하지만 인스턴스 변수의 복잡초기화는 대체로 생성자를 통한 방법을 주로 사용하고, 초기화블럭을 사용해서 복잡초기화를 진행하는 경우는 별로 많지 않다고 한다.
멤버변수의 초기화 순서
지금까지 배운 자동초기화, 간단초기화, 복잡초기화는 작동하는 순서가 있다.
가장 마지막으로 진행된 초기화를 통해 저장된 값이 변수에 마지막으로 저장될 것이니, 멤버변수의 초기화 순서를 알고 있어야 변수에 최종적으로 저장된 값이 무엇일지 추측할 수 있다.
순서는 다음과 같다.
- 자동초기화( 자료형의 default value )
- 간단초기화( 대입연산자 " = " 이용)
- 복잡초기화 중 초기화블럭
- 복잡초기화 중 생성자 ( 인스턴스 변수만 해당 )
멤버변수의 최초 초기화 시점
- 스태틱 변수 : 클래스가 처음 로딩되어 메모리에 올라갈 때 단 한번.
- 인스턴스 변수 : 객체가 생성될 때 마다.
** 스태틱 변수의 초기화 과정이 종료된 후, 그 다음에 인스턴스 변수의 초기화 과정이 진행된다.
초기화 순서 : CV → IV
위의 "멤버변수의 초기화 순서" 와 "멤버변수의 최초 초기화 시점" 개념을 바탕으로,
다음의 예제를 보고 멤버변수가 초기화되는 과정과 순서를 생각해보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class test_1 {
public static void main(String[] args) {
initiallization i = new initiallization();
System.out.println(i.iv); // 3 이 출력된다.
System.out.println(initiallization.cv); // 2 가 출력된다.
}
}
class initiallization {
static int cv = 1;
int iv = 1;
static {cv = 2;}
{ iv = 2;}
initiallization() { iv = 3; }
}
|
cs |
- initiallization 클래스가 클래스영역에 로드되고, 스태틱변수 cv 의 영역이 생성되고, 0 으로 자동초기화 된다.(int 형)
- 9행의 간단초기화(대입연산자)에 의해 스태틱변수 cv에 1 이 저장된다.
- 12행의 스태틱 초기화블럭에 의해 스태틱 변수 cv에 2가 저장된다.(복잡초기화 - 초기화블럭)
- 3행의 new 연산자에 의해서 initiallization 인스턴스가 생성되고, 객체에 인스턴스 변수 iv 의 영역이 생성된다.
그리고 인스턴스 변수 iv 가 0 으로 자동초기화 된다.(int형) - 10행의 간단초기화(대입연산자)에 의해 인스턴스 변수 iv에 1 이 저장된다.
- 13행의 인스턴스 초기화블럭에 의해 인스턴스 변수 iv에 2 가 저장된다. (복잡초기화 - 초기화블럭)
- 3행에서 initiallization( ) 생성자가 호출되어, 15행의 생성자에 의해 인스턴스 변수 iv 에 3 이 저장된다. (복잡초기화 - 생성자)
최종적으로, 스태틱변수 cv 에는 2 가 저장되었고, 인스턴스변수 iv 에는 3 이 저장되었다.
4행, 5행의 출력 결과를 통해서 답을 확인해 볼 수 있다.
22년 12월 29일 목요일 학습
'Java 문법 개념' 카테고리의 다른 글
추상클래스 vs 인터페이스 (0) | 2023.01.11 |
---|---|
오버로딩(Overloading) 과 오버라이딩(Overriding) (0) | 2022.12.29 |
참조변수 this 와 super / 생성자 this() 와 super() / 생성자 중요개념 (2) | 2022.12.28 |
Scanner 클래스의 next() , nextLine() 의 차이 (0) | 2022.12.27 |