JAVA - 생성자

생성자란 인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드이다. 인스턴스를 생성하기 위해 객체를 초기화하는 메서드가 필요한데, 생성자가 이 역할을 한다.

생성자는 기본적으로 메서드와 동일한 역할을 하는데, 메서드와 달리 아래의 두가지 조건을 필요로 한다.

  1. 생성자의 이름은 클래스의 이름과 같아야 한다.
  2. 리턴값이 없어야 한다. (리턴 타입은 생략한다.)

생성자의 조건으로 리턴값이 없어야 한다고 했다. 리턴값이 없으면 리턴 타입은 void가 되지만, 생성자를 선언할 때는 리턴 타입조차 생략된다. 어차피 생성자는 리턴값이 없기 때문에 아예 리턴 타입을 생략한다고 한다. 이는 옵션이 아닌 필수이며, 반약 void로 리턴 타입을 선언하면, 다른 클래스에서 인스턴스를 생성 할 수 없다.


생성자의 예제 코드를 보자.

Car 클래스에 String형 name 이라는 필드와 int형 number 필드를 생성했다. 그리고 CarExam 클래스에서 Car 객체에 대한 인스턴스를 생성해서 필드를 출력해보았다. Car 클래스에 필드명만 선언되었지, 값은 넣어두지 않았기 때문에 null이 출력된걸 확인할 수 있다.

여기에서 Car 클래스안에는 필드명만 선언되어있지만 사실 Car 클래스안에는 기본생성자가 자동으로 생성되어 있기 때문에 CarExam 에서 인스턴스를 생성해서 사용할 수 있었다.

이처럼 프로그래머가 따로 생성자를 만들지 않으면, 컴파일러에서 자동으로 기본생성자를 생성한다. 기본 생성자는 아래처럼 필자가 작성한것처럼 파라미터도 없고 아무런 내용도 없는 생성자를 의미한다.

1
2
3
4
5
6
class Car {
String name;
int number;

public Car() {}
}

이렇게 컴파일러에 의해 기본생성자가 자동으로 생성될 경우 각 필드값은 데이터타입에 따라 아래처럼 초기화된다.

데이터타입
int 0
double 0.0
String null
boolean false

단, 프로그래머가 따로 생성자를 만들면, 컴파일러는 기본생성자를 생성하지 않는다. 예제 코드를 통해 확인해보자.

파라미터를 받는 생성자를 Car 클래스에 생성하니, 아까 작성한 인스턴스 c1을 선언하는 코드에서 에러가 발생하는 것을 볼 수 있다.

1
The constructor Car() is undefined

더 이상 컴파일러가 기본생성자를 생성하지 않은 것이다. 기본생성자는 항상 컴파일러에서 만들어주는게 아니라 개발자가 생성자를 선언하지 않았을때만 만들어주는걸 알 수 있다.

기본생성자대신 String형 파라미터를 받는 생성자를 이용해서 name 필드를 출력해보았다.

생성자에 String형 값을 입력하니 Car 객체의 필드에 입력되어 CarExam 에서 정상적으로 출력된걸 확인할 수 있다.

이쯤에서 생성자를 사용하는 이유를 정리해보자.


생성자를 사용하는 이유

생성자를 사용하면 필수 입력값을 강제할 수 있으며, 프로그래머가 입맛대로 인스턴스를 생성(오버로딩)할 수 있게된다.

추가로, 생성자에서 this 키워드를 사용했는데, this 는 상위 scope의 객체에 접근할 때 사용하는 키워드이다.

1
2
3
4
5
6
7
public class Car {
String name;

public Car(String name){
name = name; // 아무 값도 대입되지 않음
}
}

이것처럼 Car 클래스의 필드 name과 생성자 Car(String name)에서 받는 파라미터의 이름이 같을 경우 컴파일러는 name을 인자값으로 들어온 name으로만 인식하게 된다. 따라서 이 때에 this 키워드를 사용해야, 상위 scope의 필드를 적절하게 명시할 수 있게된다.

1
2
3
4
5
6
7
public class Car {
String name;

public Car(String name){
this.name = name;
}
}