2012-08-14 5 views
1

인터뷰에서이 질문을 받았습니다. 기본 클래스 (클래스 A)와 두 개의 서브 클래스 BC이 있습니다. 이제는 B와 C의 생성자를 제어 할 수 없습니다 (해당 생성자는 비공개가 아니며 공개되어야합니다). 그러나 필요한 경우 BC의 모든 인스턴스는 단일 바이트이어야합니다. 이것을 어떻게 할 수 있습니까? 당신이 그것을 할 Double checked lockingsynchronized on method를 사용할 수 있지만어떻게 파생 클래스의 싱글 톤을 만들 수 있습니까?

+2

통제가 없다는 것은 무엇을 의미합니까? 코드를 변경할 수 없습니다 (필요하지 않음)? 또는 가시성을 변경할 수 없습니까? – Vitaliy

+0

'생성자에 대한 제어권 없음'을 정의 할 수 있습니까? –

답변

6

A에 대한 생성자에서이 작업을 수행한다고 생각합니다. 그것을 this.getClass()으로 호출하고 그것을 사용하여 개인 HashSet에서 조회를 수행하십시오. 히트를 얻으면 이전에 클래스의 인스턴스가 만들어져 예외가 발생합니다.

public abstract class A { 
    private static HashSet<Class<?>> classes = new HashSet<Class<?>>(); 

    public A() { 
     synchronized (classes) { 
      Class<?> c = this.getClass(); 
      if (classes.contains(c)) { 
       throw NotSingletonException("Class " + c + " is not singleton"); 
      } 
      classes.add(c); 
     } 
    } 
} 

A의 모든 생성자가 이렇게 정렬하면 하위 클래스가 검사를 피할 수 없습니다. JLS에서는 this() 또는 super() 호출을 try/catch 할 수 없으므로 예외가 발생하면 서브 클래스의 생성자를 정상적으로 반환 할 수 없습니다.


나는 이것이 매우 어려운 면접 질문이라고 말하고 싶지만 ...


@emory 코멘트 :

B와 C는 최종 무엇을하지 않은 경우? 그러면 B1, B2, C1, C2 등의 클래스를 생성 할 수 있습니다.

여기에서 문제가되는 것은 B1과 B2 인스턴스가 B 인스턴스이기 때문에 B 인스턴스는 더 이상 싱글 톤이 아닙니다 ... 구현하고자하는 싱글 톤의 정의에 따라 다릅니다. 당신은 반사적 클래스가 최종 경우 서브 클래스 수정보고 테스트하고 final이 아닌 클래스의 인스턴스를 생성하는 것을 거부 할 수

  • ... :

    나는이 다루는 몇 가지 방법을 볼 수 있습니다 단지를 위해.

  • HashSet<Class>List<Class>으로 바꿀 수 있습니다. 그런 다음 A 생성자가 호출 될 때마다 각 요소 클래스에 대해 elem.isAssignableFrom(c)을 호출하는 목록을 반복합니다. 어떤 호출이 true를 반환하면 (엄격한) 싱글 톤 불변 값이 위반되므로 예외가 throw되어야합니다.

논리는 싱글 - 다움이 시행하려고하는 모델에 따라 조정해야 할 수도 있습니다,하지만 일반적인 솔루션이 적용 클래스를 기록하고 검토 이전/사람과 새로운 클래스를 비교한다.

+0

B와 C가 최종이 아닌 경우 어떻게해야합니까? 그런 다음 B1, B2, C1, C2 등의 클래스를 만들 수 있습니다. 문제가있는 경우 문제를 해결할 수있는 방법은 'c'가 A가 될 때까지 'c'의 수퍼 클래스를 연속적으로 추가하는 것입니다. – emory

0

내가 클래스 B

을 위해 그것을 보여주는 있어요 ... 난 ... 당신에게 그 일의 신속하고 더러운 방법을 보여주는하고

public class B { 

    private static B b = new B(); 

    private B() {} 

    public static B getInstance() { 
      return b; 
    } 
} 
+0

수정 된 질문보기 B의 생성자는 private 일 수 없습니다. – Geek

관련 문제