생성자란 객체를 생성할 때 호출하는 메서드 비슷한 것을 말함.
주로 일반 멤버변수의 초기화나 객체를 생성할때 실행하는 작업을 정리한다.
생성자 형태 1 2 3 4 5 6 class Person{ String name; public Person(){ //생성자명은 class명과 똑같아야함 name = '홍길동'; //생성자의 주요역할은 멤버변수의 초기화 } }
특징
class명과 똑같아야함.
객체생성될때 딱 한번 호출되어짐
생성자도 overloading 가능
상속이 안되는 유일한 멤버메서드
생성자 VS void메서드 차이점
형태가 retrun값이 없는 void메서드와 비슷하게 생겼다
차이점 : 이름과 역할
이름 : 생성자는 class명과 똑같아야하고 메서드는 달라야한다.
역할 : 메서드는 다양한 기능을 담당하지만 생성자는 멤버변수의 초기화를 담당한다.
생성자를 왜 쓸까? 생성자는 자바창시자가 FM방식으로 설정했기때문이다. 자바 창시자는 생성자로 변수초기화시키고 메서드는 기능만 담당하도록 설정하고 싶었던 것이다! 자바 창시자가 정식방법으로 자바를 쓰길 원했지만 나는 한번도 쓴 적이 없는데 자바는 잘 돌아갔다. 어떻게 된 일일까?
new의 역할 나는 생성자를 한번도 생성한 적 없이 java를 사용했는데 작동에 전혀 무리가 없었다. 왜 그럴까?
바로 new 때문이다.
별도의 생성자를 만들지 않았을 때 컴파일러에 의해 컴파일 타임에 자동으로 생성자가 만들어지기 때문이다. 이를 기본생성자라고 한다.
기본생성자는 파라미터를 전달받지 않기 때문에 빈 객체를 생성한다.
기본생성자의 형태
생성자를 만들지않았지만 new라는 키워드를 통해서 BasicConstructor person = new BasicConstructor()
를 통해서 자동으로 public BasicConstructor() {}
기본연산자가 생성된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class BasicConstructor { String name; int age; boolean isHugry; public static void main (String[] args) { BasicConstructor person = new BasicConstructor(); person.name ="홍길동" ; person.age =77 ; person.isHugry = false ; } }
this 키워드 용법 this에는 두가지 용법이 있다.
this.
: 현재 객체를 참조하기 위한 용도
this()
: 다른 생성자를 호출하는 용도
멤버변수를 참조하는 this.멤버변수명
현재 객체를 참조하기 위한 용도로 사용하는 this.
먼저 보자.
아래 코드를 보자. 멤버변수명과 매개변수명을 동일하게 설정했다. 컴파일러가 첫번째 name과 두번째 name을 잘 구분할수있을까?
참고 : 생성자자동생성단축키(Generate Constructor) : Alt + Shift + S → C
매개변수로 만들고싶은 멤버변수의 체크박스를 틱하면 생성자를 생성해준다.
1 2 3 4 5 6 7 8 9 10 11 12 public class ThisPerson { String name; int age; boolean isHugry; ThisPerson(String name, int age, boolean isHungry){ name = name; age = age; isHungry = isHungry; } }
정답은 NOPE! 구분하지못한다. 이때 구분해주기위해 멤버변수명앞에 this 를 붙여준다.
1 2 3 4 5 6 7 8 9 10 11 12 public class ThisPerson { String name; int age; boolean isHugry; ThisPerson(String name, int age, boolean isHungry){ this .name = name; this .age = age; this .isHungry = isHungry; } }
이제 만든 생성자를 출력해보자. 매개변수로 받은 this.name을 출력하는 코드이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class ThisPerson { String name; int age; boolean isHugry; ThisPerson(String name, int age, boolean isHungry){ this .name = name; this .age = age; this .isHugry = isHugry; } public static void main (String[] args) { ThisPerson person = new ThisPerson("홍지민" , 20 , true ); System.out.printf("name : %s" , this .name); } }
홍지민이 출력될거라 기대했지만 출력값은 오류가 발생한다.
1 2 3 //위 코드 출력값 Exception in thread "main" java.lang.Error: Unresolved compilation problem: Cannot use this in a static context
this는 객체에 대한 참조값이다.
this는 참조값이기때문에 객체가 생성되기 전에는 사용할 수 없다.
따라서 static영역에서는 this키워드를 사용할 수 없다.
아래 코드를 출력하면 해결된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class ThisPerson { String name; int age; boolean isHugry; ThisPerson(String name, int age, boolean isHungry){ this .name = name; this .age = age; this .isHugry = isHugry; } String print () { return String.format("name : %s, age : %d" , this .name, this .age); } public static void main (String[] args) { ThisPerson person = new ThisPerson("홍지민" , 20 , true ); System.out.println(person.print()); } }
다른 생성자를 호출하는 this()
파라미터를 다르게 해서 여러 개의 생성자를 정의하는 것을 생성자 오버로딩이라고 한다.
메서드와 마찬가지로 생성자도 오버로딩이 가능하다.
생성자오버로딩하는 이유 : 다른 생성자를 호출해서 중복코드를 제거. 이때 다른 생성자를 호출하는 키워드가 this이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class OverloadConstructorPerson { String name = "한사장" ; int age = 90 ; boolean isHugry = false ; OverloadConstructorPerson(String name, int age, boolean isHungry){ this .name = name; this .age = age; this .isHugry = false ; } OverloadConstructorPerson(String name, int age){ this (name, age, false ); } OverloadConstructorPerson(String name){ this (name, 0 , false ); } OverloadConstructorPerson(){ } public static void main (String[] args) { OverloadConstructorPerson p1 = new OverloadConstructorPerson("하지" , 77 ); System.out.printf("이름 : %s, 나이 : %d%n" , p1.name, p1.age); OverloadConstructorPerson p2 = new OverloadConstructorPerson("뽀니" ); System.out.printf("이름 : %s, 나이 : %d%n" , p2.name, p2.age); OverloadConstructorPerson p3 = new OverloadConstructorPerson(); System.out.printf("이름 : %s, 나이 : %d%n" , p3.name, p3.age); } } 이름 : 하지, 나이 : 77 이름 : 뽀니, 나이 : 0 이름 : 한사장, 나이 : 90