인스턴스화 제한을 위한 private 생성자 사용

반응형
728x90
반응형

JAVA의 인스턴스화

JAVA의 인스턴스화 제한을 알아보기 전에, JAVA 인스턴스화에 대해 간단히 살펴보자. 자바에서 인스턴스란, 객체를 생성한다. 그리고, JVM이라는 자바 가상 머신이 관리하는 메모리에 적재된 상태를 뜻한다.

 

Test 기본 클래스

public class Test() {     private String a;     private String b;      public String getA() {         return a;     }      public String setA(String a) {         this.A = a;     } }

 

우리가 자주 봐왔던 자바 예제에서의 아래 한 줄이 인스턴스를 생성함을 의미한다. 위 Test 클래스의 인스턴스를 생성해보자.

 

인스턴스 생성

Test test = new Test(); 

 

위 한줄에는 많은 의미가 담겨져있다. 연산자 new에 의해서, heap 메모리에 Test 클래스의 인스턴스가 생성되었다.그리고 new 연산자에 의해서 생성된 Test 인스턴스의 주소가 참조변수 test에 저장된다. 이때 한가지 더 호출된 메소드가 존재한다. 이는 Test 클래스의 생성자이다. new 연산자에 의한 인스턴스 생성시, Test의 기본 default 생성자가 생성된다. 이때, 위 Test 예제 클래스의 코드를 보면 생성자가 선언된 곳이 없는데, 이렇게 기본 생성자를 선언하지 않으면 기본 생성자를 컴파일러가 바이트 코드에 자동으로 추가한다.

 

기본 생성자

public class Test() {     // 기본 생성자 (아래 코드는 선언하지 않아도 컴파일러가 자동 추가)     public Test() {         ...     } }

 

 

 

인스턴스화를 하지 않아야할 클래스가 존재할 경우

자바의 인스턴스화에 잠깐 알아보았다. 그런데 public의 접근제어자를 가진 기본 생성자는 어디서든 호출이 가능하다. 이 말은, 어디서든 해당 클래스의 인스턴스를 생성할 수 있다는 얘기다. 인스턴스화를 하지 않아야하는 클래스가 존재한다면? 우리는 이런 의문점을 가질 수 있다.

 

  • final 클래스와 관련된 메서드만 존재하는 클래스
  • 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 존재하는 클래스

 

위의 경우가 아니더라도 분명 인스턴스화를 막아야할 클래스가 생길 수가 있다. 하나의 해결방안으로 우리는 명시하지 않으면 컴파일러가 자동으로 추가하는 기본생성자의 생성을 막는 방법이다.

 

private 생성자

 public class Test() {     // private 생성자 선언     private Test() {         ...     } }

 

이렇게 private로 선언된 생성자는 외부에서 호출할 수 없다. 이제부터 Test 클래스의 인스턴스를 생성하려고 시도하는 코드가 존재한다면, 이는 개발자가 개발 시점에 미리 에러를 감지할 수 있는 효과를 가져온다. 이로써, Test 클래스의 인스턴스화는 어느 곳에서도 할 수 없게 되었다.

 

private 생성자 + throw Exception

 public class Test() {     // private 생성자 선언     // +) 혹시라도 같은파일 내에서 호출할 경우도 막는다.     private Test() {         throw new ***Error();     } }

 

위 코드를 보면 throw new ***Error()를 private 생성자 안에 추가되었다. private 생성자일때에 같은 파일 내에서 혹시라도 인스턴스화를 시도할 경우도 막기 위한 해결방안이다. 이렇게 throw Exception을 호출하는 private 생성자를 선언한다면, 어디서도 해당 클래스의 인스턴스를 생성할 수 없게 된다. 위 코드를 사용할때에는 다른 개발자가 private 생성자의 선언 이유를 알아챌 수 있도록 주석으로 명시해두는게 협업에 좋다.

 

 

 

private 생성자로 인한 상속 불가능

위 private 생성자로 인해, 자바의 상속도 불가능해졌다. 그이유는 무엇인지 간단히 살펴보자.

 

부모클래스의 private 생성자로 인한 상속 불가능

class Super() {
    private Super() { ... }
}

Class Sub extends Super {      
    public Sub() { ... }
}

public class Test {
    public static void main(String[] args) {
        Sub sub = new Sub();
    }
}

 

Example
- 부모클래스 : Super
- 자식클래스 : Sub

 

Test 클래스를 보면 자식 클래스인 Sub의 인스턴스를 생성하고 있다. 만약 이렇게 자식 클래스의 인스턴스를 생성한다면 자식클래스의 생성자가 호출된 이후 부모클래스의 생성자 또한 호출된다. 그렇기 때문에 private로 선언된 생성자가 존재한다면 인스턴스화가 불가함을 지금은 이해가 될 거라고 생각한다.

 

반응형

Designed by JB FACTORY