2016-09-22 5 views
2

이 클래스를 사용 :동적 파견, 과부하 및 제네릭

public class Fallible<T> { 

    private final Exception exception; 
    private final T value; 

    public Fallible(final T value) { 
     this.value = value; 
     this.exception = null; 
    } 

    public Fallible(final Exception exception) { 
     this.value = null; 
     this.exception = exception; 
    } 

} 

내가 안전하게 value 것이다 결코는 예외 객체를 포함 할 가정 수 있습니까?

답변

3

아니요, 그런 가정을 할 수 없습니다. 예 :

Object obj = new Exception(); 
Fallible f = new Fallible(obj); 

은 일반 생성자를 호출합니다.

유일한 방법이 명시 적으로 instanceof를 사용 value의 종류를 확인하는 것입니다 확인 :

public Fallible(final T value) { 
    if (value instanceof Exception) { 
    this.exception = (Exception) value; 
    this.value = null; 
    } else { 
    this.value = value; 
    this.exception = null; 
    } 
} 
+0

예외를'Object'로 넓히는 것은 정보의 손실과 동일하지만 반대의 가능성도 있습니다 :'new Fallible (new RuntimeException())'은 또한 일반 생성자를 호출 할 것이고, 이제는 명시 적 생성자보다 * 더 구체적이기 때문입니다. 그리고 이것은 아마도 의도적 인 것입니다. 올바른 솔루션은 오버로드 된 'public'생성자를 삭제하고 고유하게 지정된 factory 메소드를 사용하는 것입니다. 호출자가 의도를 문서화하고'instanceof'에 대한 필요성을 없애기 위해'value (T)'와'예외적으로 (Exception)'을 사용합니다. – Holger

+0

이러한 팩토리 메서드는 "value"가 ** Exception 객체를 포함하지 않을 것이라는 가정에 대해서는 아무 것도 추가하지 않습니다. 여전히 "Fallable.value (new Exception())"또는 "Fallible.value (obj)'. 이 클래스가 명시된 가정을해야하는 경우 방어적인 조치로 'instanceof' 확인이 필요합니다. 공개 클래스 인 경우 사용자가 불변량을 설정하는 데 올바른 일을 할 수 있다고 믿을 수 없습니다. –

+0

@Holger 실제로'value (T)'와'예외적으로 예외 (Exception) '모두'Falloy '형식이되고 싶습니다. – cuihtlauac

2

아니 당신은 할 수 없습니다.

당신은 런타임 얻는 유형 삭제 버전 고려한다면이 분석하는 것이 더 쉽습니다 :

public Fallible(final T value)public Fallible(final java.lang.Object value)이되고 있습니다.

그래서 더 좋은 일치 인 경우 오버로드 Fallible(final Exception exception)이 사용됩니다. 즉 exceptionException 또는 그 하위 클래스 유형 인 경우

java.lang.Object에서 작성을 허용하지만 Java에서 하위 클래스의 생성 (컴파일 타임에)을 금지하는 클래스를 빌드하는 것은 Java에서 불가능합니다. 런타임 검사 (instanceof & c.)에 의존해야합니다. 템플릿을 사용하여 C++에서이 문제를 해결할 수 있습니다. 이 점과 많은면에서 Java는 C++의 진화로 간주 될 때 한 걸음 더 나아가 두 단계 뒤로 돌아갑니다.