2010-08-04 5 views
0

아주 간단하고 훌륭한 아이디어였습니다. 데이터 딕셔너리 (속성 이름, 유형, 범위, 단위 등)의 세부 사항을 인코딩하고 속성 값 (i, .e., 속성 AAH)을 설정하고 읽는 유형 안전 시스템을 생성하려면 Java 5.0 열거 유형의 기능을 사용하십시오. ACC가 열거되고 ACC001, ACC002, ACC003 등의 값만 받아 들여야합니다.제네릭 형식을 서브 클래 싱하여 다른 클래스의 메서드에서 서브 클래스의 인스턴스를 반환합니다.

서로 다른 속성은 서로 다른 유형 (정수, 부동, 텍스트, 열거 형)을 가지며 각 유형의 동작이 다릅니다.

public abstract class GsAttributeValueBase<T extends Comparable<T>> { 
    protected T m_value; 
    ... 
    public GsAttributeValueBase(...) {..} 
    ... 
    public abstract void SetValue(T value) throws IllegalArgumentException; 
    public T GetValue() { return m_value; } 
    // etc., etc., etc 
} 

내가 다음 (기본적으로, 나는 가짜 부분 특수화에 노력하고있어) 각 유형이 하위 클래스 : 그래서

public class GsAttributeValueShort extends GsAttributeValueBase<Short> {...} 
public class GsAttributeValueLong extends GsAttributeValueBase<Long> {...} 
public class GsAttributeValueEncoded extends GsAttributeValueBase<GsAttributeEncodedValueEnum> {...} 
... 

그래서 나는 형식 매개 변수와 몇 가지 추상적 인 방법으로 기본 클래스를 생성 아주 좋아. 지금은 기본적으로

public GsAttributeValueBase<? extends Comparable<?>> CreateInstance() 
{ 
    switch(m_format) 
    { 
    case SHORT: return new GsAttributeValueShort(...); 
    case LONG: return new GsAttributeValueLong(...); 
    case ENCODED: return new GsAttributeValueEncoded(...); 
    ... 
    } 
} 

같은, 뭔가 (각 속성의 종류와 범위를 알고 있기 때문에)와 같은 메소드를 호출 위의 부속 유형 중 하나의 인스턴스를 반환하는 속성 열거 형의 팩토리 메소드를 만들려면 :

GsAttributeValueShort = GsAttributeEnum.AAH.CreateInstance(); 

여기가 벽돌 벽에 부딪 혔습니다. 나는 내가 지금까지) 때 CreateInstance (의 선언에 약 십여 순열을 시도했습니다

found : GsAttributeValueBase<capture of ? extends java.lang.Comparable<?>> 
required: GsAttributeValueShort 

의 순서 (는 특정 정보에 의존하기 때문에이 정적이 될 수 없습니다에 호환되지 않는 유형의 오류가 열거 인스턴스). 나는이 시점에서 내 머리카락을 찢어 버리고있다. 나는이 토끼 구멍을 내려가 며칠 동안 낭비했고, 오늘이 일을하거나 펀 트레인을해야 할 필요가있다.

정말이 작업을하고 싶습니다. 나는이 프로젝트뿐만 아니라 앞으로 진행될 다른 프로젝트에도 가치가 있다고 생각합니다. 그러나 Java generics는 C++ 템플릿 (지난 주에 복수로 집에 돌아온 것)과 같이 행동하지 않으며, 여기서 중요한 무엇인가를 놓치고 있다는 것을 알고 있지만 그것이 무엇인지는 알 수 없습니다.

나는 내 머리 속에서 상상 그리고 난 그것에 너무 많은 시간을 점화 한이 작품에게 길을 만들 수 없습니다

편집 할 수 있습니다. 제안 해 주셔서 감사합니다.하지만 저는이 문제를 마무리하겠습니다.

편집 2

오. 나는 내 자신의 질문을 닫을 수 없다. 오 잘.

답변

0

그냥지도와 my TypeSafeMap pattern을 사용하십시오.

제네릭에 대한 몇 가지 생각 : 제네릭은 컬렉션을 안전하게 보호하기위한 것입니다. 런타임시 타입 안전 클래스를 작성하는 것과 같은 복잡한 작업을위한 것은 아닙니다. 그러므로 짐을 지우지 않도록 도구를 사용하십시오. 캐스트가 으로 작동하는 경우 일반 구문이 작동하는 방식을 이해하지 못합니다 (방금 쓴 경우에도 해당). 캐스트를 사용하십시오. 반년 만에이 코드로 돌아와서 고쳐야한다고 상상해보십시오.

+0

"그들은 정말 런타임에 유형 안전 클래스를 구축 같은 복잡한 것들에 대한 것이 아닙니다." 그건 대담한 진술입니다. 얼마나 많은 사람들이 동의하는지 궁금합니다. –

+0

@Kirk : Java 컴파일러로부터 제네릭 관련 오류 메시지가 나타날 때 혼란스러워하는 Java 개발자의 90 %. 내 말은 : 소수의 사람들 만 제네릭을 타입 안전 컬렉션 이상으로 사용할 수 있다는 것을 잘 알고 있습니다. –

+0

충분합니다. 제네릭이 다른 용도로 사용될 수 없다는 것을 암시한다고 생각했습니다. :) –

3

무엇에 대해 :

public <T extends Comparable<T>> GsAttributeValueBase<? super T> CreateInstance() { 
    ... 
} 
+0

아마도 또한'? 슈퍼'와'GsAttributeValueBase'를 사용합니다. –

+0

기쁨이 없습니다. 이제 CreateInstance() 메서드에서 호환되지 않는 형식 오류가 발생합니다. 결과를 캐스팅하려고하면 (새로운 (GsAttributeValueBase ) GsAttributeValueShort (...)를 반환합니다), 나는 inconvertable type error를 얻습니다. –

+0

호환되지 않는 유형 오류입니까? 아니면 "체크되지 않은 캐스트"입니까? (그냥 경고와 함께 캐스트로 샘플 코드를 컴파일 할 수있었습니다.) –

관련 문제