2011-01-28 4 views
0

두 개의 파서 클래스가 있으며 구문 분석에 실패하면 예외가 발생합니다. 나는 같은 예외, ParserException을 사용하고 싶다. 나는 실패의 원인이 된 필드 이름을 받아 들일 수있다. 열거 형을 사용하려고 생각했지만 주제가 완전히 명확하지 않다고 생각합니다.특정 열거 형 클래스의 수퍼 유형 매개 변수 사용

어떻게 ParserException 클래스에서 fieldName을 선언합니까? enum은 내가 이해하는 한 ParserA.Fields 및 ParserB.Fields의 상위 유형이어야하지만 허용되지 않습니다.

두 열거 형 클래스에는 다른 열거 집합이 들어 있습니다. 즉, 두 클래스는 동일한 클래스가 아닙니다.

public class ParserA { 

public enum Fields { 
    A_FIRST_FIELD 
    A_SECOND_FIELD 
} 


public void parse() { 
    ... 
throw ParserException(Fields.A_FIRST_FIELD); 
} 

} 

public class ParserB { 

public enum Fields { 
    B_FIRST_FIELD 
    B_SECOND_FIELD 
} 

public void parse() { 
    ... 
    throw ParserException(Fields.B_FIRST_FIELD); 
} 

} 



// Parser error 
public class ParserException extends Exception { 

enum fieldName; // ????? what goes here? 


public ParserException(enum e) { 
    this.fieldName = e; 
} 

public enum getFieldName() { // ?????? how do I do something like this? 
    return fieldName; 
} 

} 

답변

0

글쎄, 당신 ParserException 저장 Enum<?>을 가지고 있지만, 이것은 정말 그냥 ParserException에서 필드의 유형으로 Object를 사용하는 동안 당신에게 실질적인 이점을 제공하지 않습니다. 당신이 무슨 일을하는지의 디자인을 변경 짧은

, 내 취향은 Field라는 마커 인터페이스를 만들고 필드 ... 다음 ParserException이 유형으로 Field을 사용할 수 있다는 구현 표현의 모든 enum의를하는 것입니다 저장하는 객체의 대부분의 경우

public interface Field { 
} 

... 

public enum Fields implements Field { 
    A_FIRST_FIELD, 
    A_SECOND_FIELD 
} 

... 

public class ParserException extends Exception { 
    private final Field field; 

    public ParserException(Field field) { 
    this.field = field; 
    } 

    public Field getField() { 
    return field; 
    } 
} 

는, 뭔가가 enum 다른 아무것도 걱정 할 필요가 없습니다 것을 구현 세부해야한다.

+0

'이것은 Object를 사용하는 것 이상의 진정한 이점을 제공하지 않습니다. -'name()'과'ordinal()'메소드는 정말 편리 할 것입니다. OTOH, 당신은 더 이상 이런 식으로 얻을 수 없습니다. – maaartinus

+0

@maaartinus :'toString()'은'toString()'을 오버라이드하지 않는 한'name()'과 동일하다.'name()'의 Javadoc은'toString()'이 그것보다 우선적으로 사용된다는 것을 암시한다 대부분의 경우에. 'ordinal()'은 일반적인 사용을 목적으로하지 않습니다 ... "정교한 enum 기반 데이터 구조에서 사용하도록 설계되었습니다". – ColinD

+0

나는 동의하지 않는다. "* 대부분의 프로그래머는 toString 메서드를이 메서드보다 우선 사용해야합니다."- 이상하게 들립니다. 'toString()'은 사람에게 사용되어야하지만, 프로그램의 행동은 그것에 의존해서는 안됩니다. 그게'name()'의 목적입니다. 그리고 cdarwin이'ordinal()'으로 정교한 구조를 만들지 누가 알겠는가? 물론, 당신이 할 수있는 일은 많지 않습니다. 특히 당신이 가지고있는 두 열거 형 중 어느 것을 알지 못할 때. – maaartinus

0

평범한 클래스와 마찬가지로 Fields 유형을 사용하십시오.

Fields fieldName; 

그리고 다른 경우에는 유사합니다.

보통 열거 형은 대개 단일 이름으로 명명됩니다 (클래스와 마찬가지로 열거 형은 이 아니며이 아닙니다).

당신은 Enum 클래스 (모든 열거 형에 대한 공통의 슈퍼 클래스)를 사용할 수 있습니다
편집, 또는 Object.

하지만 솔직히 말해 하나의 요소로 enum 클래스를 선언하는 데는 별다른 의미가 없습니다. 당신은 방금 문자열 상수를 사용할 수있었습니다 : 똑같은 기능과 덜 혼란 스럽습니다.

+0

두 개의 Fields 클래스가 다르다면 샘플 코드를 편집 할 것입니다 ... – cdarwin

+0

분명히 열거 형은 둘 이상의 요소를 포함하고 있습니다 .... 나는 코드를 다시 편집 할 것입니다 – cdarwin

+0

@cdarwin이 경우' Enum'이해야합니다. 도움이되지는 않지만 이름은 문자열 일 수도 있습니다. –

0

ParserA.FieldsParserB.Fields에는 일반 슈퍼 클래스가 없습니다 (원시 유형 Enum 또는 Object 제외).하지만 여기가 도움이 될 것으로 생각됩니다.

열거 형을 확장 할 수 없으므로 열거 형을 사용하여이 문제를 해결할 수있는 방법을 알 수 없습니다.

당신은 classenum을 변경하여이 문제를 해결하고 모두 ParserA.FieldParserB.FieldParserException.Field을 확장 할 수 있습니다. 그러나 enums과 동일한 이점을 얻으려면 인스턴스 수를 제한해야합니다. 이를 달성하는 데는 생성자를 보호하는 등 여러 가지 방법이 있으며이 유형의 정적 정적 멤버의 수가 제한되어 있습니다.

+0

나는 또한 다른 해결책을 받아 들인다. 그러나 어떤면에서는 열거 형을 사용해야한다고 생각한다. – cdarwin

+0

적어도 때때로 인터페이스를 사용하여 해결할 수있다. – maaartinus

+0

-1이 사용 사례의 열거 형을 클래스로 변경하는 것은 용납되지 않습니다. 여러 enum이 일부 공통 유형을 구현하도록하려면 인터페이스가 적절합니다. – ColinD

1

열거는, 지금까지의 내가 이해하는 한, ParserA.Fields에 대한 슈퍼 타입과 ParserB.Fields

하지 열거해야하지만, 열거 공통 상위 유형 (또는 더 정확하게 Enum<?>). 그러나 아마 당신은 그것을 사용하고 싶지 않습니다, 너무 일반적입니다.

// ParserExceptionKind is probably a better name 
public interface ParserEnum { 
     String name(); 
     // some useful methods go here 
} 

public class ParserA implements ParserEnum { 
     public enum Fields { 
      A_FIRST_FIELD 
     } 
} 

public class ParserException extends Exception { 
     private ParserEnum parserEnum; 
     ... 
} 

그러나 대부분의 경우 Exception의 별도 하위 클래스를 만드는 것이 더 좋습니다.