2012-06-23 2 views
1

일반 기본 클래스를 반환하는 팩터 리 메서드를 일반화하려고합니다. 그것은 작동하지만, 내가 받고있어 "BaseClass 원시 형식입니다 ..."경고.Java - Factory 제네릭 기본 형식을 반환하는 메서드

나는 일반적인 방법에 대한 자바 문서 인 을 읽었지만 여전히 이것을 달성하는 방법을 아직 알지 못했다.

클래스 # 1

//base abstract class 
public abstract class BaseFormatter<T> 
{ 
    public abstract String formatValue(T value); 
} 

클래스 # 2

//two implementations of concrete classes 
public class FooFormatter extends BaseFormatter<Integer> 
{ 
    @Override 
    public String formatValue(Integer value) 
    { 
     //return a formatted String 
    } 
} 

클래스 # 별도의 클래스에서 3

public class BarFormatter extends BaseFormatter<String> 
{ 
    @Override 
    public String formatValue(String value) 
    { 
     //return a formatted String 
    } 
} 

공장 방법

0 : 여기에

는 일부 코드입니다 코드

BaseFormatter<Integer> formatter = getFormatter(someInteger); 
formatter.formatValue(myIntegerToFormat); 

문제는 getFormatter() 방법으로 다른 장소에서 공장 방법에이

public static BaseFormatter getFormatter(Integer unrelatedInteger) 
{ 
    if (FOO_FORMATTER.equals(unrelatedInteger)) 
     return new FooFormatter(); 
    else if (BAR_FORMATTER.equals(unrelatedInteger)) 
     return new BarFormatter(); 
    //else... 
} 

전화는 BaseFormatter 원시 형, 그것이 있음을 경고합니다. 나는 BaseFormatter와 같은 다양한 것을 시도했다 그 외 여러분. 물론 호출 메서드의 BaseFormatter에서와 같이 반환 형식을 일반 형식으로 설정합니다.

형식 지정자 유형은 클래스 유형을 기반으로하지 않습니다. 예 : 모든 정수는 값은 FooFormatter로 포맷됩니다. 정수 (또는 문자열 또는 목록)의 형식을 지정할 수있는 방법은 2-3 가지입니다. 그게 param unrelatedInteger가 대상입니다.

의견에 대해 미리 감사드립니다. getFormatter가 BaseFormatter에 정의되어있는 경우

+0

간단한 대답 : 자바 유형 시스템은 안전하게 원하는 제약 조건을 표현할 수 없습니다. 즉,이 캐스트에 대한 경고를 제거 할 수 없습니다. – millimoose

답변

0

후 사용 getFormatter이 BaseFormatter 아닌 다른 클래스에 정의되어있는 경우

public static BaseFormatter<T> getFormatter(Integer unrelatedInteger) 

는 다음 사용

public static BaseFormatter<?> getFormatter(Integer unrelatedInteger) 
+0

BaseFormatter 을 할 경우 다음과 같이해야합니다. public static BaseFormatter getFormatter (정수 변환기). 새로운 FooFormatter()를 반환하면 오류가 발생하므로이 작업을 수행 할 수 없습니다. FooFormatter를 BaseFormatter 으로 변환 할 수 없으므로 작동하지 않습니다. –

+0

@TedJones 내 업데이트 참조 –

+0

업데이트를 읽었습니다. 문제는 다음과 같습니다. getFormatter는 다른 클래스에서 정의됩니다. Unknown (BaseFormatter ) 형식의 BaseFormatter를 반환하면이 메서드는 만족 스럽습니다. 하지만 호출 메서드에서 BaseFormatter를 수행 할 수 없습니다. formatter = getFormatter (someInteger); 형식 불일치 오류가 발생합니다. 그것을 BaseFormatter로 변경하면 formatter = getFormatter (someInteger); 그 형식이 알려지지 않았기 때문에 Integer를 전달할 수 없습니다. Integer가 아닙니다. –

0

을 당신은 actuaaly 아무 관련이 없다는 것을 말하는 것 형식화 된 매개 변수 BaseFormatterunrelatedInteger 사이의 값은 getFormatter 메서드에 대한 인수로 전달됩니다.

Uncehcked Assignment: BaseFormatter to BaseFormatter<Integer> 

이 경고는 당신이 표시된 것보다 더 나쁘다 :

나는 다른 경고를 얻을.

BaseFormatter<Integer> myUnsafeFormatter = 
     FormatterFactory.getFormatter(unrelatedIntegerForBarFormatter); 

컴파일러는 관련이 없습니다 : 그것은이 사용자 코드가하는 BaseFormatter<String>BaseFormatter<Integer>에 삽입 런타임에 실패 할 경우에만 ... 사용자가 실수로 같은처럼 팩토리 메소드를 사용하여 고려 발견 될 뭔가를 시도 할 수 있다고 경고 매개 변수화 된 유형이 BaseFormatterunrelatedInteger입니다.

대체적으로, 사용자가 명시 적으로 콘크리트 포맷터 생성자를 사용하게 할 수 있습니다. 모든 포맷터가 공유하는 모든 공통 코드는 FormatterUtils 클래스에 넣을 수 있습니다 (단지 utils 클래스가 훨씬 커지지 않도록 ...).

0

학술적 언어의 일부 유형 시스템은 소위 종속 합계를 나타낼 수 있습니다. 자바는 분명히 할 수 없다. 분명한 것은, getFormatter 메소드에 의해 돌려 주어지는 오브젝트의 타입이 무엇인가? 우리가 할 수있는 최선책은 IntegerString이 공통적으로 Object 뿐이므로 BaseFormatter< ? extends Object > 또는 짧게는 BaseFormatter<?>입니다.

원래 포스트가 질문을 던지기 때문에 어떤 포맷터를 반환할지 결정하기 위해 정수를 사용해야하는 이유와 호출자가 형식 지정자 유형을 알 수없는 경우 호출자는 왜 더 강력한 변수 유형이 필요한가? BaseFormatter<?>?

+0

글쎄, 기술적으로 아무것도 필요하지 않습니다. BaseFormatter 이상. 문제는 데이터 형식이 동일한 동일한 format() 메서드를 호출하여 정렬 인터페이스로 BaseFormatter를 사용한다는 것입니다. Object를 취하고 올바른 타입으로 캐스팅하기 전에. 이것은 물론 클래스 캐스팅 예외가 있기 때문에 문제였습니다. 이를 generic화할 때 format (arg) 메소드에서 데이터 유형을 강제 실행하는 것이 합리적입니다. 다른 포맷터가 다른 유형을 사용하기 때문에 필자는 수퍼 클래스에서 T를 사용해야합니다. 내가 생각할 수있는 유일한 대안은 (다음 게시물 계속) –

+0

BaseFormatter 대체 formatter = getFormatter (someInteger); 에 if 문을 입력하고 올바른 형식 지정 프로그램을 인스턴스화하십시오. 여러 위치에서 호출되었으므로 절름발이입니다. 이 코드를 공통된 위치에 두었습니다. 그러나 FooFormatter와 BarFormatter가 동일하게 작동하도록 (예 : 동일한 메소드 호출, 다른 argtype), 구현해야하는 추상 메소드가있는 수퍼 클래스가 필요합니다. 내가 고려하고있는 또 하나의 솔루션은 CommonFormatter를 가지고 있고 format()을 오버로드하는 것이므로 cf.format (unrelatedInteger, myIntToFormat, cf.format (unrelatedInteger, myStrToFormat))을 수행 할 수있다. (다음 게시물에 계속) –

+0

형식 (두 개 이상 있지만이 예제에서는 2로 유지), 각 메서드는 일련의 if 문을가집니다. 예 :'if (FOO_FORMATTER.equals (unrelatedInteger)) // do foo formatting; else if (BAR_FORMATTER.equals (unrelatedInteger)) // 바 형식화하기'나는 그다지 좋아하지 않습니다. 누구에게나 제안이 있으면 열려 있습니다. –

관련 문제