서론
어느날 갑자기 이런 생각이 떠올랐다.
클래스에 매개변수가 존재하는 생성자가 있으면 기본 생성자가 굳이 필요한가?
왜 매개변수가 존재하는 생성자를 만들어주면 항상 기본 생성자를 만들어줘야하지?
왜 기본 생성자를 안 만들어주면 왜 가끔 에러가 나는거야?
기본 생성자는 도대체 왜 필요한거지?
Stackoverflow에선 이렇게 답변하는 사람도 있었다.
"I don't have a good answer for 'why'. Because that's how the language was built."
-> "언어가 그냥 그렇게 만들어졌어 나도 몰라"(아 몰라 그냥 그런줄 알고 있어)
그래서 조금 객체지향적인 관점에서 설명해보려고 한다.
슈도 코드
기본 생성자가 필요한 이유를 설명하기 위해선 상속에 대한 설명이 필요하다.
public Class 부모 { //기본 생성자가 없어서 에러 발생
부모(int i){ //매개변수가 있는 생성자
}
}
public Class 자식 extends 부모 {
자식() { //내부적으로 만들어진 기본 생성자
super();
}
}
위의 슈도 코드를 보자면 자바는 모든 클래스에 내부적으로 기본 생성자를 갖고 있다.
자바는 내부적으로 부모 Class처럼 개발자가 매개변수가 있는 생성자를 만들면 기본 생성자는 만들지 않는다.
그리고 자식 Class에서는 부모 Class를 상속 받고 있다.
자식 클래스에서는 항상 내부적으로 생성된 기본 생성자에서 super()를 이용해 부모의 정보를 불러온다.
그렇기 때문에 부모 클래스는 자식 클래스에게 자신의 정보를 줄 준비를 해야하기 때문에 항상 기본 생성자가 필요한 이유다.
자식은 항상 내부적으로 super() 명령어를 이용해 부모의 기본 생성자를 부르기 때문이다.
해결 방법
자식의 기본 생성자가 부모의 기본 생성자를 참조 할 수 있도록 부모에서 기본 생성자를 만들어준다.
혹은 자식의 기본 생성자를 직접 커스터마이징해서 super에 매개변수를 던진다. 그렇게 하면 부모는 기본 생성자가 필요 없다.
부모(int i){ // 부모 클래스에 매개변수가 있는 생성자만 있다면
}
자식() { // 자식 생성자에서는 super를 커스터마이징해서 사용한다.
super(1);
}
생성자를 호출하지 못하게 하기 위한 용도가 아니라면 기본 생성자를 없애는 것은 그리 좋은 선택은 아니다.
상속이라는 객체지향적 관점에서 모든 클래스는 자신의 기본 정보인 기본 생성자에 연결이 되도록 만들어져 있다.
JackSon과 JPA
위와는 다르게 Jackson이나 JPA Entity 사용 시에 내부적으로 기본 생성자를 강제하는 경우가 있는데 이런 경우엔 기본 생성자를 '무조건' 만들어줘야 한다.
Jackson을 예로 들자면 @RequestBody 은 경우 DTO에 값을 세팅 하기 위해(Setter가 아니라) delegate(생성자 안에서 다른 생성자 호출)를 통해 기본 생성자를 호출하게 된다.
JPA의 경우 Entity 객체에 값을 세팅하기 위해 (Setter가 아니라) Reflection을 사용한다.
리플렉션이란 구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API
리플렉션의 Class.newInstance()를 사용해서 생성자 코드를 만드는데 이때 이 코드가 바라보는게 바로 기본 생성자다.
또한 DTO의 직렬화(다른 자바 프로그램에도 사용하기위함) 클래스에서도 항상 기본 생성자가 필요하다.
위의 나열된 기술들을 사용 할 땐 내부적으로 '매개변수가 들어있는 생성자가 있을 시'를 고려하는 코드가 존재하지 않고(그럴 수도 없을 뿐더러) 항상 기본 생성자를 이용해서 인스턴스화를 공통적으로 처리를 하기 때문이다.
기본 생성자만 있으면 값 세팅을 어떻게 하냐고? 그럴때 쓰라고 있는게 Setter다. Setter 이외에도 다른 기능을 이용해 값을 따로 할당하게 되는 기능으로 구현하면 된다.
'☕ Java' 카테고리의 다른 글
JSP와 자바빈(JavaBean) (0) | 2022.02.15 |
---|---|
[Java vs Node.js] 무엇이 더 좋을까? (0) | 2022.01.23 |
[JSP] 캐시 방지 & 캐시 삭제 팁 (0) | 2021.03.22 |
JSP 내에 쓰일 수 있는 태그 종류 (0) | 2021.01.21 |
람다식의 이해와 사용 (0) | 2021.01.12 |