자바의 생성자(constructor)

    자바의 생성자란?


    객체 생성 직후에 객체의 데이터들을 초기화하는 기능을 가지고 있는 메서드입니다. 생성자는 자바에서 객체 생성 시에 반드시 필요합니다.

     

     

     

     

    생성자가 왜 필요한 것일까?


    자바 프로그래밍을 하다 보면 객체를 생성하고 난 뒤에 곧바로 초기화를 통해 초기값을 지정해 주어야 하는 경우가 많습니다. 그래서 자바에서는 객체를 생성하고 나서 즉시 초기화를 진행하거나 특정 기능들을 수행하도록 하는 기능을 가진 메서드인 생성자를 제공합니다.

     

    아래의 코드를 비교하면서 생성자를 정의하고 객체를 작성자가 직접 정의하는 것과 정의하지 않고 자동으로 작성되는 기본 생성자의 차이를 알아봅시다.

    package construction;
    
    public class Person {
        public String name;
        public int age;
        public int height;
        public int birth;
    }
    package construction;
    
    public class PersonMain {
    	public static void main(String[] args) {
            Person person = new Person();
            person.name = "길동";
            person.age = 19;
            person.height = 180;
            person.birth = 2005;
        }
    }

     

    위 Person 클래스의 객체를 생성하기 위해, 참조형 변수를 선언해서 person. 을 활용해 일일이 인스턴스 변수의 값을 초기화시킵니다. 위와 같이 하나하나 값을 넣어주면 코드를 작성하는 입장에서 굉장히 불편합니다.

     

    이때 자바에서는 다음과 같이 생성자를 클래스에서 미리 정의해 주어서 편리하게 값을 초기화할 수 있습니다.

    package construction;
    
    public class Person {
        public String name;
        public int age;
        public int height;
        public int birth;
        
        public Person(String name, int age, int height, int birth) {
            this.name = name;
            this.age = age;
            this.height = height;
            this.birth = birth;
        }
    }
    package construction;
    
    public class PersonMain {
    	public static void main(String[] args) {
    		Person person = new Person("길동",19,180,2005);
            //위 매개값을 인스턴스 변수에 저장함.
        }
    }

     

    첫 번째 형태와 같이 사용자가 필드값만 선언하고 생성자를 직접 작성하지 않은 경우, 자바에서는 기본 생성자의 형태로 생성자를 자동으로 작성해 줍니다.

    package construction;
    
    public class Person {
        public String name;
        public int age;
        public int height;
        public int birth;
    
        /*
        public Person() {} //자바가 자동으로 생성함.
        */
    }

     

     

    작성자가 직접 생성자를 정의하고 싶은 경우, 다음과 같은 형태로 생성해 줍니다.

    생성자의 작성 방법


    public Person(String name, int age, int height, int birth) {
        this.name = name;
        this.age = age;
        this.height = height;
        this.birth = birth;
    }
    1. 먼저 접근 제한자와 클래스명을 작성하고, 우측 괄호 안에 인스턴스 변수에 데이터를 넣어줄 매개 변수를 선언합니다.
    2. 구현부 내부에 this. 필드 = 매개변수; 형태로 값을 대입해 주는 코드를 작성합니다.

    생성자 작성 시에 무조건 모든 필드에 데이터를 넣어 줄 필요는 없습니다. 원하는 필드에만 넣고 싶다면 해당 필드에만 매개변수의 값을 대입해 주는 형태로 작성해 주면 됩니다.


    this


    위 코드를 보면 생성자 내부 필드 명 앞에 this라는 키워드를 작성하였습니다. 이 키워드를 작성한 이유가 뭘까요?

     

    this를 작성하지 않으면, 위 매개변수가 필드 보다 더 우선순위에 있기 때문에, 매개변수에 접근을 하게 됩니다. 따라서, 매개 변수 안에 매개변수를 넣어주는 꼴이 됩니다.

     

    이를 방지하고 매개 변수가 아닌 필드에 접근하기 위해서 this를 작성해서 객체 자신의 참조 값을 가리키게 됩니다.

    public Person(String name, int age, int height, int birth) {
         this.name = name; //@515f550a.name = name;
    }

     

    만약 매개 변수와 필드의 이름이 다르다면, this를 생략하는 것이 가능합니다.

     

    생성자는 위와 같이 값을 초기화하는 역할뿐만 아니라, 또 다른 동작을 수행할 수 있습니다.

    public Person(String name, int age, int height, int birth) {
    	this.name = name;
    	System.out.println(name + "님 환영합니다.");
    }

     

    위와 같이 객체 생성 시에 수행할 동작을 정의할 수 있습니다.

     

    이렇게 보면 일반적인 메서드와 비슷한 것이 아닌가 라는 의문점이 들지만 다음과 같은 차이가 있습니다.

    • 생성자의 이름은 메서드와 다르게 클래스명으로 해주어야 합니다. 따라서 첫 글자도 대문자로 작성해야 합니다.
    • 메서드는 반환타입을 지정해서 특정 데이터를 반환할 수 있지만, 생성자는 반환 타입을 비워 두어야 합니다.

    메서드를 통해서 값을 초기화하는 것보다, 생성자를 통해서 초기화하는 것이 더 편하고 빠르기 때문에 값을 초기화하는 기능이라면 메서드보다는 생성자를 활용하는 것이 더 효율적일 것입니다.

     

     

     

    생성자 오버로딩


    생성자도 메서드처럼 매개변수만 다르게 해서 오버로딩이 가능합니다.

    package construction;
    
    public class Person {
        public String name;
        public int age;
        public int height;
        public int birth;
        
        public Person(String name, int age, int height, int birth) {
            this.name = name;
            this.age = age;
            this.height = height;
            this.birth = birth;
        }
        
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
            if (age < 19) {
                System.out.println(name + "님, 접속이 불가능합니다.")
            } else {
            	System.out.println("환영합니다.")
            }
       	}
    }

     

    메서드 오버로딩과 마찬가지로 객체 생성 시에 생성자의 매개값에 어떤 값을 입력하느냐에 따라서 생성자가 자동으로 선택됩니다.

     

     

    this()


    this()를 활용해서 생성자 내부에서 같은 클래스의 다른 생성자를 불러올 수도 있습니다.

    package construction;
    
    public class Person {
        public String name;
        public int age;
        public int height;
        public int birth;
        
        public Person(String name, int age) {
            this(name,age,180,0223); //오버로딩 된 아래의 생성자를 호출
            if (age < 19) {
                System.out.println(name + "님, 접속이 불가능합니다.");
                return;
            } 
            System.out.println("환영합니다.");
        }
        
        public Person(String name, int age, int height, int birth) {
            this.name = name; 
            this.age = age;
            this.height = height; //180
            this.birth = birth; //0223
            //필드값 초기화 후 다시 기존 생성자로 돌아가서 남은 기능 수행
       	}
    }

     

    매개 값을 두 개만 입력할 경우 첫 번째 Person() 생성자가 호출되어 기능을 수행하게 됩니다. 첫 줄에 this()를 통해서 전달받은 매개 변수 두 개와 기존에 미리 작성한 리터럴 값을 더하여 오버로딩 된 생성자로 전달합니다.

     

    오버로딩 된 생성자에서는 전달받은 매개 변수 4개를 통해 필드 값 초기화 작업을 진행 한 다음 다시 기존에 호출한 생성자로 돌아가서 남은 기능들을 수행합니다.

     

    주의할 점

    this()는 항상 생성자의 첫 줄에만 작성이 가능합니다. 두 번째 줄 이상부터 작성할 경우 컴파일 오류가 발생합니다.

    'Backend > Java' 카테고리의 다른 글

    자바의 배열(array)  (2) 2024.03.01
    자바의 final  (0) 2024.02.28
    자바의 패키지(package)  (2) 2024.02.16
    자바의 기본형과 참조형  (0) 2024.02.13
    자바의 클래스(Class)  (0) 2024.02.12

    댓글