2012-12-27 5 views
23

javadoc for Void는 말한다 :Void는 실제로 인스턴스를 해제 할 수 있습니까?

공허 클래스는, Java 키워드 void를 나타내는 Class 객체에의 참조를 보관 유지하는 uninstantiable 자리 클래스입니다.

하지만 생성자는 단순히 :

private Void() {} 

는이 코드가 Void 인스턴스화

Constructor<Void> c = Void.class.getDeclaredConstructor(); 
c.setAccessible(true); 
Void v = c.newInstance(); // Hello sailor 

그래서 Void는 uninstantiable 하지입니다.

Void을 실제로 언 스탁 할 수 없게 만드는 방법이 있었습니까?

+2

을 : 당신이 그것을 필요합니까? ;) 나는 그것이 _returning_'void' 메쏘드에 대한 리플렉션 API를위한 자리 표시 자일 뿐이라고 생각합니다 ... 아마도 프록시에 대해서만 도움이 될까요? – fge

+2

리플렉션을 사용하는 경우 API를 사용하여 수행 할 수없는 많은 작업을 수행 할 수 있습니다. – kosa

답변

28

생성자의 개인 만들기, 외부에서 액세스 할 수있는 다른 생성자를 가지고 있지를, 클래스가 않은 인스턴스화 있습니다.

그러나 Reflection API을 사용하여 액세스하지 못하게 할 수는 없습니다. 리플렉션을 사용하면 정상적으로 허용되지 않는 작업을 수행 할 수 있습니다.

그러나, 당신은 정말 당신의 클래스도 생성자에서 반사, 당신이 할 수있는 throw 체크되지 않는 예외을 통해 uninstantiable,되고 싶어합니다. 당신이 Constructor#newInstance() 방법을 사용하여 인스턴스를 만들 때 @ 알렉스에 의해 주석에 인용

private MyClass() { 
    throw UnsupportedOperationException("Can't instantiate class"); 
} 

하는 경우, 그것은, InvocationTargetException 발생합니다. 여기

그들 중 하나가 InvocationTargetException입니다 던져 질 예외의 목록을 선언 Constructor#newInstance() 방법의 문서이고, 그것은 말한다 : -

예외 :
있는 InvocationTargetException을 - 기본 생성자 가 발생하는 경우 예외.

+1

예외를 체크하지 않아야한다고 생각하지 않습니다. 검사 된 객체 (아마도'java.lang.IllegalAccessException'?)를 던진 경우에도 작동합니다. – matts

+0

+1 예외를 throw하는 것은 그것을 수행하는 방법입니다 :) – Bohemian

+2

@matts 여기에 검사되지 않은 예외가 선호 될 것이라고 생각합니다. 하나는 적은 코드 ('throws' 조항 없음)를 만드는 것이고, 이것은 항상 좋은 일입니다. – Bohemian

10

Reflection API는 final 필드를 수정할 수있는 것처럼 모든 종류의 '규칙'을 위반합니다. Java의 강력하고 빠른 규칙을 깨뜨릴 수 있다는 사실에 대해 많은 불만이 있습니다. 그렇지만 그것이 사실입니다.

반사가 없으면 (또는 @ StevenSchlansker의 미친 Unsafe API가 게시 됨) 인스턴스를 생성 할 수 없습니다. Reflection이 허용되는 한 이러한 대안이 존재합니다.

Oracle's own Reflection tutorial에는 이점과 단점이 나열되어 있습니다. 어떤 것이 더 큰지는 당신에게 달려 있습니다. 또한

,이 질문을 참조하십시오 What is reflection and why is it useful?

29

Rohit은 예외를 throw하는 것이 대부분의 사용 사례에 대해 "충분 함"입니다.

공공 네이티브 오브젝트 allocateInstance (클래스 CLS) 있는 InstantiationException

인스턴스를 할당 있지만 생성자를 실행하지 않는 던져 그러나, 그것은 bypass even that, using sun.misc.Unsafe에 수도있을 것 같습니다. 클래스가 아직 초기화되지 않은 경우 초기화합니다.

(나는 실제로 작동하는지 테스트되지 않았 음을 참고) 호기심에서

+23

와우. 그것은 무서운 API입니다. – asteri

관련 문제