목차
개요
본 포스팅은 클래스 내부에 생성자가 하나라도 선언되지 않았을시에 자바 인터프리터에서 기본 생성자(Default constructor)를 생성해주는 인터프리터 기능에 대한 레퍼런스 자료이다.
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.8.9
Section 8.8.9 "Default Constructor"
1. 컴파일러는 자바 코드에서 생성자를 명시적으로 선언하지 않으면 기본 생성자를 자동으로 생성
2. 이 기본 생성자를 통해 객체의 인스턴스 변수는 기본값으로 초기화되고 상위 클래스의 생성자가 호출
추가적으로 래퍼런스 내에서 기본생성자에 대한 특징을 나타낸것
- [조건] 클래스에 생성자가 명시적으로 선언되지 않으면 기본 생성자가 암시적으로 선언
- 기본 생성자는 클래스와 동일한 접근성을 가진다.
- 기본 생성자는 형식 매개변수가 없으며, 예외 처리를 위한 throws 절도 존재하지 않는다.
- 기본 생성자는 상위 클래스 생성자를 인수 없이 호출
좀더 디테일하게 설명해주고 있다.
예제 번역본
예제 8.8.9-1. Default Constructors:
클래스에 생성자가 명시적으로 정의되어 있지 않으면, 컴파일러는 기본 생성자를 자동으로 추가한다.
기본 생성자는 public일 수도 있고, 클래스의 접근 수준에 따라 다른 접근 수준을 가질 수도 있다.
이 예제에서 Point 클래스는 명시적으로 생성자를 정의하지 않았기 때문에, 컴파일러가 자동으로 기본 생성자를 추가하며, 클래스가 public이므로 기본 생성자도 public이다.
예제 8.8.9-2. Accessibility of Constructors v. Classes:
이 예제는 생성자와 클래스의 접근성 간의 차이를 보여주는데 Outer 클래스는 public이며, Inner 클래스는 protected이다.
SonOfOuter 클래스는 다른 패키지에 있고, p1.Outer 클래스를 상속받는다.
SonOfOuter 클래스에서 Inner 클래스는 SonOfOuter가 Outer의 하위 클래스이기 때문에 접근이 가능하다.
하지만
Inner 클래스의 기본 생성자는 SonOfOuter가 Inner의 하위 클래스가 아니기 때문에 SonOfOuter에서 접근이 불가능하다.
따라서 Inner 클래스는 접근 가능하지만, 기본 생성자는 접근할 수 없다.
그럼 우리는 Inner의 클래스를 접근할 방법이 없을까?
1. Inner을 protected가 아닌 public 으로 바꾸자!
A. 좋다. 근데 그건 본 포스팅의 취지에 알맞지 않,,, protected된 즉 제한사항이 걸려야하는 이유가 있으니
생성자 접근 수준(접근제어자를 변경)을 바꾸는건 안된다. (뒤에 왜 이런 방식을 취하는지 서술함)
2. Outer 클래스에 '팩토리 메서드' 라는 기능을 구현해주자
package p1;
public class Outer {
protected class Inner {
}
// 팩토리 메서드를 추가하여 Inner 객체를 생성
public Inner createInner() {
return new Inner();
}
}
public의 접근 제어자으로 Inner 객체 생성을 하는 메서드를 만들어냈다.
기술적으로는 : 객체 생성 로직을 서브클래스에게 위임해 객체 생성의 로직을 분리했다. 라고 말할수 있다.
그렇게 되면 아래와 같은 코드로 SonOfOuter가 Inner 객체를 생성할 수 있게된다.
package p2;
import p1.Outer;
class SonOfOuter extends Outer {
void foo() {
// Outer 클래스의 팩토리 메서드를 사용하여 Inner 객체를 생성
Inner inner = createInner();
}
}
그럼 왜 이렇게 하는 것일까??
- 캡슐화
팩토리 메서드를 사용하면 객체 생성 과정을 캡슐화하여, 외부 클래스가 내부 클래스의 생성 과정에 대한 지식을 최소화할 수 있다. 이렇게 하면 코드의 결합도를 낮추고 유지 보수를 용이하게 할 수 있다. - 유연성
팩토리 메서드를 사용하면 객체 생성 전략을 쉽게 변경할 수 있다.
조금 풀어 말하자면 지금은 멤버변수가 적고 간단한 식이지만 나중에 Inner에 많은 멤버변수가 생기고 Inner에서 파생된 객체들이 많아진다면 이 방법을 사용하지 않고는 객체들을 하나하나 다 생성시켜줘야겠지만 이런 팩토리 메서드를 사용해 객체들의 수정이 있을때 해당 메서드만 수정해주면 된다. - 생성 로직 중앙화
팩토리 메서드를 사용하면 객체 생성 로직을 중앙화하여, 코드 중복을 방지하고 버그를 방지할 수 있다. 또한 객체 생성 시 필요한 초기화 작업이나 검증 작업을 한 곳에서 처리할 수 있다. - 접근 제어
protected로 지정하면 Inner 클래스의 생성자에 대한 접근을 제한할 수 있다.
이렇게 하면 Inner 객체를 생성하는 것을 외부 클래스와 그 서브클래스로 제한하고, 내부 클래스의 상태와 동작을 더욱 잘 보호할 수 있다.
'Java' 카테고리의 다른 글
JVM스택메모리 구조 이해를 위한 바이트코드 예시 (0) | 2024.06.25 |
---|---|
JVM에서 자바 메서드와 네이티브 메서드 실행의 차이점 (0) | 2024.06.24 |
Optional: 안정적인 Null 처리 그리고 orElse(), orElseGet(), orElseThrow() 에 대한 이해 (0) | 2023.10.24 |
객체지향에서의 클래스 간의 관계[IS, HAS, USES, REALIZE,DEPEND-ON] (0) | 2023.04.28 |
문자열 조작에 있어서 오버헤드 발생 이유 (StringBuffer, StringBuilder 차이) (0) | 2023.04.14 |