[Java] 생성자와 this키워드

김용준·2022년 9월 29일
0

Java Basic

목록 보기
17/22

생성자란?

  • 객체 생성 직후 실행되는 메소드다.
  • 매개변수를 통해 객체의 멤버변수를 초기화한다.
  • 반환값이 없다.
  • 객체 생성시 new연산자와 함께 사용한다.

조건

생성자도 클래스 내에 선언되는 메소드이지만 다음 조건을 만족해야 생성자로 간주한다. 반환값이 없는 메소드이지만 void라는 키워드를 사용하지 않는다. 그저 반환타입 자체를 사용하지 않는다.

  • 생성자 이름은 클래스 이름과 같아야 한다.
  • 메소드의 선언부에 반환타입이 없다.

기본 생성자

  • 매개변수가 없는 생성자이다.
  • 소스파일에서 직접 정의하지 않아도, 클래스파일로 컴파일 될 때 자동으로 생성된다. 단, 클래스에 정의된 생성자가 하나도 없어야 한다.

생성자도 메소드이기 때문에 오버로딩이 가능하다. 그래서 매개변수가 있는 생성자를 정의하면 자동으로 기본 생성자가 생성되지 않는다. 이미 생성자가 정의되어 있기 때문이다. 따라서 매개변수가 있는 생성자를 정의했다면 반드시 기본 생성자를 정의해주어야 매개변수 없이 객체를 생성할 수 있다. 그렇지 않을 경우 에러가 발생한다.

생성자 예제

다음 예제를 통해 생성자가 어떻게 사용되는지 구체적으로 이해해 보자. Car클래스를 기본 생성자와 매개변수를 갖는 생성자를 오버로딩했고, Car클래스로부터 생성자를 이용해 객체를 생성하고 객체의 멤버변수를 출력한 예제이다.

public class Car {

	String name;
	String maker;
	int price;
	
    // 기본 생성자를 정의한다.
	public Car() {
		
	}
	
    // carName과 carMaker를 매개변수로 하는 생성자 메소드를 오버로딩했다.
	public Car(String carName, String carMaker) {
		name = carName;
		maker = carMaker;
	}
   
    // carName, carMaker, carPrice를 매개변수로 하는 생성자 메소드를 오버로딩했다.   
    public Car(String carName, String carMaker, int carPrice) {
		name = carName;
		maker = carMaker;
		price = carPrice;
	}
}
public class CarApp {


	public static void main(String[] args) {

		String carName = "3-series";
		String carMaker = "BMW";
		
        // 3-series와 BMW를 인자로 전달하여 Car객체를 생성한다.
		Car car = new Car(carName, carMaker);
		
		System.out.println("이름: " + car.name);
		System.out.println("제조사: " + car.maker);
		System.out.println("가격: " + car.price);
	}
}
출력

이름: 3-series
제조사: BMW
가격: 0

같은 이름의 메소드를 오버로딩했기 때문에 매개변수의 개수에 맞는 메소드가 자동으로 실행되었다. 객체의 멤버변수가 전달받은 인자로 초기화 되었다. 그러나 인자가 없던 price는 기본값으로 초기화되었다.

앞서 언급했던 것처럼 매개변수가 있는 생성자를 정의하고 기본 생성자를 정의하지 않았을 때는 다음과 같은 에러가 발생한다.

말그대로 기본 생성자 Car()가 정의되지 않았다는 의미이다.

생성자 실행 과정

위의 예제를 통해 생성자를 실행할 때 JVM이 수행하는 작업을 이해해보자.
Car car = new Car()는 다음과 같은 과정으로 수행된다.

  1. 생성자와 동일한 이름의 클래스를 메모리의 Method영역에 로딩하고, 기본 생성자를 자동으로 추가한다.
    • Car.class를 Method영역에 로딩, 기본 생성자 메소드 Car()추가

  2. 로딩된 클래스를 통해 Heap영역에 객체를 생성한다.
    • Heap영역에 Car객체 생성

  3. 생성된 객체에 포함된 생성자 메소드를 실행한다.
    • 생성자 메소드 Car() 실행

  4. 객체의 주소값을 참조변수에 대입한다.
    • 참조변수 carCar객체의 주소값 대입

this 키워드

객체가 생성되면 그 객체 내부에 this라는 이름을 가진 변수가 자동으로 생성된다. 변수 this에는 해당 객체 자신의 주소값이 저장되어 있다.
따라서 this키워드를 통해 해당 객체의 멤버 변수나 메소드에 접근할 수 있다.

this 참조변수

객체를 생성한 후, 참조변수명.필드명으로 객체의 멤버변수에 접근할 수 있다. 마찬가지로 this를 이용해 this를 포함하는 객체의 멤버변수에 접근할 수 있다. 클래스를 정의할 때, 메소드의 매개변수와 필드명을 구분하기 위해 사용한다.

this() 메소드

한 생성자에서 다른 생성자를 호출할 때 사용한다. 반드시 생성자 내부에서만 사용 가능하며, 생성자의 실행문 중 첫 번째 줄에 위치해야한다.

this 키워드 예제

다음의 예제는 위에서 다룬 예제를 this키워드를 이용해 재구성한 것이다.

public class Car {

	String name;
	String maker;
	int price;
	
    // 기본 생성자이고 생성과 동시에 지정해둔 값으로 멤버변수를 초기화한다.
	public Car() {
		this("3-series", "BMW", 5000);
	}
	
    // 세 번째 생성자의 maker에 "BMW"를 인자로 전달한다.
	public Car(String name, int price) {
		this(name, "BMW", price);
		
	}
	
	// this를 통해 매개변수와 필드명을 구분했다.
	public Car(String name, String maker, int price) {
		this.name = name;
		this.maker = maker;
		this.price = price;
	}
}
public class CarApp {


	public static void main(String[] args) {

		Car car1 = new Car();
		Car car2 = new Car("5-series", 8000);
		
		System.out.println("Car1 이름: " + car1.name);
		System.out.println("Car1 제조사: " + car1.maker);
		System.out.println("Car1 가격: " + car1.price);
		System.out.println();
		System.out.println("Car2 이름: " + car2.name);
		System.out.println("Car2 제조사: " + car2.maker);
		System.out.println("Car2 가격: " + car2.price);
	}
}
출력

Car1 이름: 3-series
Car1 제조사: BMW
Car1 가격: 5000

Car2 이름: 5-series
Car2 제조사: BMW
Car2 가격: 8000

마찬가지로 매개변수의 개수에 따라 자동으로 메소드가 선택된다.
기본 생성자를 통해 생성한 Car1은 이미 클래스에서 정의된 값으로 멤버변수가 초기화되었다.
Car2"BMW"를 인자로 전달받은 세 번째 생성자가 먼저 실행된 후 해당 객체의 생성자가 실행되었기 때문에 멤버변수 maker"BMW"로 초기화 되어있다.

profile
차선이 모여 최선이 된다.

0개의 댓글