[Java] 초기화(순서)

이현준·2020년 9월 29일
0

Java

목록 보기
1/15

자바 객체의 초기화 순서는?

[부모가 있을시에]--------
1. 부모의 명백한 초기화와 초기화 블록 (선언, 정의된 순서대로 실행됨)
2. 부모의 생성자 몸체
----------------------------
3. 자식의 명백한 초기화와 초기화 블록 (선언, 정의된 순서대로 실행됨)
4. 자식의 생성자 몸체

예제 코드

public class A {
	//명백한 초기화
	private String parentProcess = "부모의 명백한 초기화";
	
	//초기화 블록
	{
		System.out.println(parentProcess);	//부모의 명백한 초기화 출력
		System.out.println("부모 초기화 블록 호출");
		parentProcess = "부모 초기화 블록";
		System.out.println(parentProcess);	//부모 초기화 블록 출력

	}
	public A(String parentProcess) {
		System.out.println("부모 생성자 몸체 호출");
		System.out.println(this.parentProcess); //부모 초기화 블록 출력
		this.parentProcess = parentProcess;
		System.out.println(this.parentProcess); //main 호출 출력

	}
	

}

public class B extends A {
	//초기화 블록
	{
//		System.out.println(process);
		System.out.println("자식 초기화 블록 호출");
		process = "자식 초기화 블록";
//		System.out.println(process);
	}
	
	//명백한 초기화
	private String process = "명백한 초기화";
	public B(String process) {
		super(process);
		System.out.println(this.process); //명백한 초기화 호출 출력
		System.out.println("자식 생성자 호출");
		this.process = process;
		System.out.println(this.process); //main 호출 출력

	}

	public static void main(String[] args) {
		B b1 = new B("main 호출");
	}

}

콘솔 출력 결과

추가

  • 모든 객체마다 값이 똑같을 거 같으면 명백한 초기화
  • 객체마다 값을 받아서 초기화해줄거면 생성자 초기화

기억해야될 점

  • 자식 클래스 객체를 생성하면 해당 생성자에서 부모 생성자를 호출하여 부모로부터 상속받은 멤버 변수를 초기화해야 함
  • 만약 자식 클래스에서 직접 부모 생성자를 호출하지 않으면 자동으로 부모의 기본 생성자가 호출됨
  • this, super를 이용한 호출은 항상 생성자의 첫 문장으로 사용해야 함
    (안 그러면 Constructor call must be the first statement in a constructor 라고 뜬다.)
  • tihs와 super 를 동시에 사용할 수 없음
public class Person {
	private String name;
	public Person(String name) {
		this.name = name;
	}
}


public class Student extends Person {
	private String id;
	private int year;
	public Student(String name, String id) {
		this(name, id, 1);
	}
	
	public Student(String name, String id, int year) {
    		//부모 생성자를 호출해서 부모로부터 상속받은 멤버변수 초기화, Person(name)한다고 보면 됨
		super(name); 
		this.id = id;
		this.year = year;
	}

	public static void main(String[] args) {
		Student hylee = new Student("hylee", "2015");

	}

}

public class A {
	private int n = 0;
	public A() {
		System.out.println("부모 기본 생성자 ");	
	}
	public A(int n) {
		System.out.println("부모 생성자");	
		this.n = n;
	}
}

public class B extends A {
	private int x = 1;
	public B(int x) {
		System.out.println("자식 생성자");	
		this.x = x;
	}
}

  • 이와 같이 자식 생성자 B 에서 부모 생성자를 호출하지 않으면( (super()) 안 씀 ) 자동으로 부모의 기본 생성자가 호출된다

public class A {
	private int n = 0;
	//부모 A의 기본 생성자 없음 
	public A(int n) {
		System.out.println("부모 생성자");	
		this.n = n;
	}
}

public class B extends A {
	private int x = 1;
	public B(int x) {
		System.out.println("자식 생성자");	
		this.x = x;
	}
}//error

  • 자식 생성자 B 에서 부모 생성자를 호출하지 않았으므로 자동으로 부모의 기본 생성자가 호출되지만 부모의 기본 생성자가 정의되어 있지 않으모로 에러가 뜬다!
  • 그래서 상속관계에서는 부모가 기본 생성자를 만들어주는게 일반적이다. (자식쪽에서 에러날 수 있기 때문에)

public class A {
	private int n = 0;
	//부모 A의 기본 생성자 없음 
	public A(int n) {
		System.out.println("부모 생성자");	
		this.n = n;
	}
}

public class B extends A {
	private int x = 1;
	public B(int x) {
    	super(x);
		System.out.println("자식 생성자");	
		this.x = x;
	}
}//ok

  • 여기서 super로 정수 하나 받는 생성자를 호출하기 때문에 OK이다!

0개의 댓글