[자바JAVA]클래스 : 생성자, new역할, this키워드용법

생성자

  • 생성자란 객체를 생성할 때 호출하는 메서드 비슷한 것을 말함.
  • 주로 일반 멤버변수의 초기화나 객체를 생성할때 실행하는 작업을 정리한다.
  • 생성자 형태
    1
    2
    3
    4
    5
    6
    class Person{
    String name;
    public Person(){ //생성자명은 class명과 똑같아야함
    name = '홍길동'; //생성자의 주요역할은 멤버변수의 초기화
    }
    }
  • 특징
    • class명과 똑같아야함.
    • 객체생성될때 딱 한번 호출되어짐
    • 생성자도 overloading가능
    • 상속이 안되는 유일한 멤버메서드




생성자 VS void메서드 차이점

  • 형태가 retrun값이 없는 void메서드와 비슷하게 생겼다
  • 차이점 : 이름과 역할
    • 이름 : 생성자는 class명과 똑같아야하고 메서드는 달라야한다.
    • 역할 : 메서드는 다양한 기능을 담당하지만 생성자는 멤버변수의 초기화를 담당한다.




생성자를 왜 쓸까?

생성자는 자바창시자가 FM방식으로 설정했기때문이다.
자바 창시자는 생성자로 변수초기화시키고 메서드는 기능만 담당하도록 설정하고 싶었던 것이다!
자바 창시자가 정식방법으로 자바를 쓰길 원했지만 나는 한번도 쓴 적이 없는데 자바는 잘 돌아갔다.
어떻게 된 일일까?

  • 바로 아래 NEW에 답이 있다.




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 BasicConstructor() {} //생략된 기본 생성자

public static void main(String[] args) {

//new연산자가 BasicConstructor()를 호출하면 컴파일러가 자동으로 기본생성자를 만든다
BasicConstructor person = new BasicConstructor();

//기본생성자이므로 외부에서 객체의 멤버 변수를 설정해줘야한다
person.name ="홍길동";
person.age =77;
person.isHugry = false;
}
}




this 키워드 용법

this에는 두가지 용법이 있다.

  1. this. : 현재 객체를 참조하기 위한 용도
  2. 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; //컴파일러가 첫번째 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){
//아래 3줄의 중복코드가 발생함.
this.name = name;
this.age = age;
this.isHugry = false;
}

OverloadConstructorPerson(String name, int age){
//this()용법사용
this(name, age, false);
}

OverloadConstructorPerson(String name){
//this()용법사용
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