글
빈도가 되게 높다고는 할 수 없는 부분이지만,
빼놓을 수도 없는 부분인 인스턴스 초기화 블럭 파트입니다.!
일단 , 쓰임새에 대해서 알아볼까요?
1) 인스턴스 데이터 멤버를 초기화 할 때 인스턴스 초기화 블록을 사용합니다.
2) 클래스의 객체가 생성될 때 마다 인스턴스 초기화 블록이 실행됩니다.
초기화 블럭의 정의 아래와 같습니다.
초기화 블럭(initialization block)
• 클래스 초기화 블럭 : 클래스 변수의 복잡한 초기화에 사용된다. 클래스가 처음 로딩될 때 한번만 수행된다.
• 인스턴스 초기화 블럭 : 인스턴스 변수의 복잡한 초기화에 사용된다. 인스턴스가 생성될때 마다 수행된다. (생성자보다 먼저 수행된다.)
Q)아래 코드처럼 개발자가 직접 인스턴스 데이터 멤버에 값을 줄 수 있는데,
왜 굳이 인스턴스 초기화 블럭을 사용하나요?
class bike {
int speed = 100;
}
A) 왜 인스턴스 초기화 블럭을 사용하는가?
인스터스 데이터 멤버에 값을 할당하면서 for 반복문으로 복잡한 배열이나 에러 처리 같은 어떤 동
작을 수행해야한다고 가정해봅시다.
package instance_initialize_block;
public class InstanceTest01 {
public static void main(String[] args) {
bike7 b1 = new bike7();
bike7 b2 = new bike7();
}
}
class bike7{
int speed;
public bike7() {
System.out.println("speed = " + speed);
// TODO Auto-generated constructor stub
}
{speed = 100;}
}
output=
speed = 100
speed = 100
여기서보면,
bike7 클래스안에 별도의 {}블럭이 생성되어있고
speed = 100;으로 초기화시켜주고있네요.
일단 인스턴스 초기화 블럭의 모양이 저런 모양이구나 하고 넘어가봅시다.
자바에서 동작을 수행할 수 있는 곳은 세 곳이 있습니다.
- 메소드
- 생성자
- 블럭<<<<
그렇다면, 블럭이 위치한 로컬에 있는 변수의 초기값을 블럭의 내용대로 적용이 된것을 알 수가 있겠죠?
———————
그렇다면, 인스턴스 블럭과 생성자 중에 무엇이 먼저 실행 될까요?
예제를 살펴보죠,
package instance_initialize_block;
public class InstanceTest02 {
public static void main(String[] args) {
bike8 b1 = new bike8();
bike8 b2 = new bike8();
}
}
class bike8{
int speed;
public bike8() {
System.out.println("생성자가 호출되었습니다.");
//생성자
}
{System.out.println("인스턴스 초기 블럭이 호출되었습니다.");}
// 인스턴스블럭
}
bike8이라는 테스트용 클래스를 만든 후
생성자에 프린트를 찍어줍니다.
그리고 블럭을 삽입해 둘 중 누가 먼저 실행될지에 대해서 테스트해보도록하죠.
메인 메소드를 가지고있는 InstanceTest02 클래스에
bike8클래스 객체를 만들어서 테스트해보도록하겠습니다.
위 상태로 실행시키면, b1이 실행되고 b2가 실행되겠죠.
이때 생성자가 먼저 호출이 될건지, 블럭이 먼저 호출이 될건지 봅시다.
의외로 생성자가 먼저 호출이 된 결과값이네요.
왜그런지 알아볼까요?
실은, 인스턴스 초기화 블럭이 먼저 호출이 되는 것처럼보이지만은,
객체가 생성될때 인스턴스 초기화 블럭이 호출됩니다. ( 거의 동시에)
자바 컴파일러는 첫 문장 super() 키워드 이후에 생성자 안에 있는 인스터스 초기화 블럭을 카피합니다.
그래서 결과값과는 살짝 다르게 생성자를 먼저 호출하는 셈이죠.
아래에 이해를 돕는 예제와 표를 첨부했습니다.
위에 표에서는 숨어있던 super()가 나오네요 !
실행 순서는
super() > instance initialize block > constructor of local 순서가 되겠네요.
bike클래스가 상속받을 parentOfBike클래스를 만들어주고
생성자에 프린트문으로 찍어줍니다.(누가 먼저 호출되는지 구분하기위해서)
별 다른 설명이 없습니다.
실행하였을때
super()로 부모클래스의 생성자가 호출되고
인스턴스 초기화 블럭에 있던 구문이 실행되고
로컬 클래스에 생성자가 호출되었네요.
이제 이해가 가시나요?
안가신다면 잠시 여유를 가져보는 건 어떨까요?
인스턴스 초기화 블럭은 주된 3가지 규칙에 의해 사용되는데
아래와 같습니다.
1) 인스턴스 초기화 블럭은 클래스의 인스턴스가 생성될 때 생성됩니다.
2)부모 클래스 생성자를 호출한 후 인스턴스 초기화 블럭이 호출됩니다.
3) 인스턴스 초기화 블럭은 기술된 순서대로 나타납니다.
마지막 예제를 보시죠!
부모 클래스를 만들고~
A를 상속할 B3클래스를 만들어주고~
생성자에 super()키워드를 넣어줍니다.
오버로드한 생성자에 int a라는 매개 변수를 삽입하고
B3클래스 최하단에 인스턴스 초기화 블럭을 선언해줍니다.
그리고는 객체를 만들 때 매개변수를 준 객체와 안준 객체를
생성하면 어떻게 될까요?
결과값을 보면 이해가 잘 되시나요?
다시한번 되짚어보자면
super() > instance initializer block > constructor of local class.
꼭 기억하시고 열공하시길 바랍니다 :)
'프로그래밍발전소 ♫ > JAVA 발전소♫' 카테고리의 다른 글
자바 Final Keyword 2편! (0) | 2017.08.08 |
---|---|
자바 Final Keyword 1편! (0) | 2017.08.07 |
JAVA super keyword -3 (자바 슈퍼키워드 3편) (0) | 2017.08.03 |
JAVA super keyword 에 대해서 2 (자바 슈퍼키워드 -2 ) (1) | 2017.08.03 |
JAVA의 super keyword에 대해서 , ( 자바 슈퍼키워드) (1) | 2017.08.02 |
RECENT COMMENT