[JAVA] 생성자

용용학생·2024년 4월 21일

자바

목록 보기
15/32

생성자

생성자는 인스턴스의 초기화를 위한 특별한 메소드이다.

클래스를 공부할 때 Tv 클래스의 인스턴스를 생성하는 법을 배웠다.

	Tv t = new Tv();

이 때, new 연산자 뒤에 오는 Tv()가 생성자이다.

생성자라는 용어 때문에 인스턴스 생성을 생성자가 하는 줄 알지만
생성자는 그저 인스턴스 변수들의 초기화를 위한 메소드이다.
인스턴스의 생성은 new 연산자가 한다.

Tv t = new Tv();

  • 연산자 new에 의해 메모리(Heap)에 Tv 클래스의 인스턴스 생성
  • Tv( ) 생성자가 호출되어 수행
  • new의 결과로 생성된 Tv 인스턴스의 주소가 반환되어 변수 t에 저장

조건

생성자 역시 메소드처럼 클래스 내에 선언되며, 구조도 메소드와 유사하지만 몇 가지 조건이 있다.

  • 생성자의 이름은 클래스의 이름과 같아야 함
  • 생성자는 리턴 값이 없음

생성자가 리턴 값이 없지만 '리턴값이 없음'을 뜻하는 void를 사용하지는 않고, 아무 것도 적지 않는다.

생성자도 오버로딩이 가능하기 때문에 여러 개의 생성자가 있을 수 있다.

class Tv {
	int size;
	String color;

	Tv() { ... } // 매개변수가 없는 생성자
    
    Tv(int s, String c) { ... } // 매개변수가 있는 생성자
}

기본 생성자

모든 클래스에서는 생성자가 반드시 하나 이상 정의되어 있어야 한다.
그러나 생성자를 정의하지 않고도 정상적으로 프로그램이 실행이 되었는데, 그 이유는 컴파일러가 제공하는 기본 생성자 때문이다.

컴파일할 때, 소스파일( *. java )의 클래스에 생성자가 하나도 정의되어 있지 않다면 컴파일러가 자동적으로 클래스이름( ) { }의 형태로 기본 생성자를 추가한다.

class A {
	int a;
}

class B {
	int b;
    B(int x) { b = x; }
}

class Main {
	public static void main(String[] args) {
    	A a = new A();
        B b = new B(); // 컴파일 에러

위와 같이 실행한다면 B 인스턴스를 생성할 때 컴파일 에러가 발생한다.
그 이유는 B의 클래스에는 int형 매개변수를 받는 생성자가 이미 있기 때문에
기본 생성자 는 추가되지 않기 때문이다.

기본 생성자가 컴파일러에 의해 추가되는 경우는
클래스에 정의된 생성자가 없을 때이다.

매개변수가 있는 생성자

class Tv {
	int size;
	String color;

	Tv() { } // 매개변수가 없는 생성자
    
    Tv(int s, String c) { // 매개변수가 있는 생성자
    	size = s;
        color = c;
    } 
}

class Main {
	public static void main(String[] args) {
    	// 매개변수 없는 생성자 사용 및 필드 따로 초기화
    	Tv t = new Tv();
        t.size = 65;
        t.color = "Black";
        
        // 매개변수 있는 생성자 사용 + 필드 동시 초기화
        Tv v = new Tv(65, "Black");
  • 매개변수가 없는 생성자를 사용한다면, 인스턴스 생성 후 필드를 따로 초기화해주어야 함
  • 매개변수가 있는 생성자를 사용하면, 인스턴스를 생성하면서 동시에 필드를 초기화해줄 수 있어서 코드가 간결하고 직관적임

다른 생성자 호출 - this()

메소드가 메소드를 호출할 수 있는 것처럼, 생성자도 생성자를 호출할 수 있다.
단, 두 가지 조건을 만족시켜야 한다.

  • 생성자의 이름으로, 클래스이름 대신 this를 사용
  • 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출
Tv(int size) {
	this(size, "Blue");
    color = "Black";
}

위의 코드처럼 this( )를 통해 다른 생성자를 호출해야하고
생성자 호출이 맨 첫 줄에 와야 한다.

생성자 호출이 첫 줄에 와야 하는 이유는 초기화 도중 다른 생성자를 호출하여 필드 초기화가 다시 진행되면 이전에 행한 초기화가 무의미해질 수 있기 때문이다.

  • this( )를 이용해 생성자를 유기적으로 연결하면 더 좋은 코드를 얻을 수 있다
class Car {
	String color;
    String gearType;
    int door;
    
    // Car() {
    // 	  color = "white";
    //    gearType = "auto";
    //    door = 4;
    // }
    
    Car() {
    	this("white", "auto", 4);
    }
	
    Car(String c, String g, int d) {
    	color = c;
        gearType = g;
        door = d;
    }

인스턴스 변수들의 디폴트 값이 있다면 이런 방식으로 유기적으로 연결하여 사용할 수 있다.

this

this( )와는 완전히 다른 문법이다.
this( )는 생성자 이고, this 는 참조 변수 이다.

바로 위의 코드에서 color = c 부분은 생성자의 매개변수로 선언된 변수 c의 값을
인스턴스 변수 color 에 저장한다. 이 때에 매개변수와 인스턴스변수는 이름만으로 구분되기에 문제가 없다.

하지만, 만약 매개변수의 이름도 color 로 지정된다면 두 변수가 구별이 되지 않는다.

이런 경우 인스턴스 변수 앞에 this를 사용하면 된다.

Car(String color, String gearType, int door) {
	this.color = color;
    this.gearType = gearType;
    this.door = door;
}
  • 생성자를 포함한 모든 인스턴스메소드에는 자신과 관련된 인스턴스를 가리키는 참조변수 this가 숨어있다
  • 인스턴스를 가리키는 참조변수이기에 static 메소드에서는 사용 할 수 없다
profile
자바 스프링 공부하는 정리 블로그!

0개의 댓글