Java SE Tutorials/Constructors

Java Constructors

Soul-Learner 2016. 12. 5. 18:41

Java 프로그래밍, 생성자 ( Constructors )


생성자(Constructor)

Java 언어의 생성자는 객체를 생성할 때 반드시 요구되는 코드 블럭이며 메소드와 유사하지만 클래스명과 동일해야 하고 리턴타입을 가지지 않아야 한다. Java로 작성된 모든 클래스에는 반드시 1개 이상의 생성자가 선언되어 있어야 오류가 발생하지 않는다. 그래서 개발자가 클래스를 선언할 때 생성자를 정의하지 않으면 컴파일시에 컴파일러가 디폴트 생성자, 혹은 기본 생성자를 포함하여 컴파일하게 된다.

예를 들어 아래와 같은 클래스가 있을 때, 개발자는 클래스 안에 생성자를 선언하지 않았기 때문에 자바 문법을 충족하기 위해서 컴파일러는 컴파일시에 기본 생성자를 포함하고 컴파일을 하게 된다

참고 : 객체 생성(Object Creation)과 인스턴스 생성(Instance Creation)은 동일한 의미이다


생성자를 정의하지 않은 클래스의 선언

class User
{
	int num;     
	String name;
	String email;
	
	// 이 메소드는 접근제한자가 public이므로 외부에서 접근(호출)이 가능하다
	public void printUser()
	{
		System.out.println("====== 회원정보 ======");
		System.out.printf("\t 번호 : %d %n", num);
		System.out.printf("\t 이름 : %s %n", name);
		System.out.printf("\t 메일 : %s %n", email);
	}
}

위와 같이 작성자가 생성자를 정의하지 않은 클래스는 문법적으로 완전하지 않기 때문에 컴파일러는 작성자 대신에 디폴트 생성자(기본 생성자)를 삽입하고 컴파일을 수행하게 된다


디폴트 생성자(기본 생성자), Default Constructors

위에 예로든 User 클래스를 컴파일하는 중에 컴파일러가 포함시킨 기본 생성자는 다음과 같은 형식을 가진다

class User
{	
	// 컴파일러에 의해 추가된 기본 생성자(Default Constructor)의 형식
	// 기본 생성자의 Access Modifier 는 클래스와 동일하게 설정됨
	User() 
	{
		super();
	}
	
	int num;     
	String name;
	String email;
	
	// 이 메소드는 접근제한자가 public이므로 외부에서 접근(호출)이 가능하다
	public void printUser()
	{
		System.out.println("====== 회원정보 ======");
		System.out.printf("\t 번호 : %d %n", num);
		System.out.printf("\t 이름 : %s %n", name);
		System.out.printf("\t 메일 : %s %n", email);
	}
}


객체 생성(Object Creation) 및 생성자의 기능

생성자는 주로 객체 생성시에 인스턴스 멤버변수를 초기화하는 용도로 사용된다. 객체가 생성된 직후에 실행되어 객체의 속성(인스턴스 변수)을 초기화하는 용도로 사용하는 것이 적절한다

위에 선언된 User 클래스의 객체를 생성하는 문장은 다음과 같다

User user = new User();

  1. 참조변수 생성 : User 형 참조변수 user 선언
  2. 생성자 연쇄호출 : 현재 클래스의 생성자가 호출되면 연쇄적으로 상위클래스의 생성자를 호출함(super())
  3. 객체생성 : 생성자의 연쇄호출이 끝나면 현재 클래스의 인스턴스 변수를 Heap 영역에 로드함
  4. 묵시적 초기화 : 인스턴스 변수는 각 자료형의 기본 값으로 초기화함
  5. 명시적 초기화 : 인스턴스 변수 선언시에 코드상에서 주어진 값으로 초기화됨
  6. 생성자 바디 : 생성자의 바디에 정의된 문장이 실행됨( 예를 들어, 인스턴스 변수 초기화 로직 등)
  7. 인스턴스 참조 리턴 : 생성된 인스턴스(객체)의 참조(주소)가 리턴되어 참조변수 user에 할당된다


인스턴스 생성 및 사용 예

public class Tutorials 
{
	public static void main(String[] args) 
	{
		// 객체 생성
		User user = new User();
		
		// 객체의 초기화
		user.num = 10;
		user.name = "홍길동";
		user.email = "hong@naver.com";
		
		// 인스턴스 메소드 호출
		user.printUser();
	}
}

class User
{
	int num;     
	String name;
	String email;
	
	// 이 메소드는 접근제한자가 public이므로 외부에서 접근(호출)이 가능하다
	public void printUser()
	{
		System.out.println("====== 회원정보 ======");
		System.out.printf(" 번호 : %d %n", num);
		System.out.printf(" 이름 : %s %n", name);
		System.out.printf(" 메일 : %s %n", email);
	}
}


생성자 오버로드 ( Constructor Overload ) : 클래스 안에 다수개의 생성자를 정의하는 것

파라미터가 없는 생성자와 파라미터를 가진 생성자를 함께 선언하여 객체 생성시 편의를 제공함

public class Tutorials 
{
	public static void main(String[] args) 
	{
		// 객체 생성, 파라미터를 가진 생성자를 호출함
		User user = new User(10,"홍길동", "hong@naver.com");
		
		// 객체의 초기화, 생성자를 이용하여 초기화했으므로 아래 라인은 불필요함
		//user.num = 10;
		//user.name = "홍길동";
		//user.email = "hong@naver.com";
		
		// 인스턴스 메소드 호출
		user.printUser();
	}
}

class User
{
	int num;     
	String name;
	String email;
	
	// 생성자를 오버로드할 때는 파라미터의 타입, 갯수, 순서 등을 달리 해야한다
	// 첫번째 생성자. 파라미터 없음
	User() { 
		//super();
	}
	
	// 두번째 생성자. 파라미터 있음
	User(int num, String name, String email){
		this.num = num;
		this.name = name;
		this.email = email;
	}
	// 이 메소드는 접근제한자가 public이므로 외부에서 접근(호출)이 가능하다
	public void printUser()
	{
		System.out.println("====== 회원정보 ======");
		System.out.printf(" 번호 : %d %n", num);
		System.out.printf(" 이름 : %s %n", name);
		System.out.printf(" 메일 : %s %n", email);
	}
}