2012-05-17 6 views
0

나는 다음과 같은 코드가 다음 코드에서자바 제네릭과 인터페이스, 매개 변수

public interface IDoWork<K extends AbstractKey,V extends AbstractClass> { 
    V obtain(K key, V value); 
} 

public class AbstractKey { 
    String id; 
} 

public class AbstractClass { 
    String name; 
} 

public class ConcreteA extends AbstractClass { 
    String attributeA; 
} 

public class DoWorkA implements IDoWork<KeyA, ConcreteA> { 

    private static final DoWorkA INSTANCE = new DoWorkA(); 

    public static DoWorkA getInstance() { 
     return INSTANCE; 
    } 

    @Override 
    public ConcreteA obtain(KeyA k, ConcreteA v) { 
     //do something in real life 
     return null; 
    } 

} 

public class Main { 

    public static void main(String[] args){ 
     KeyA a = new KeyA(); 
     ConcreteA c = new ConcreteA(); 
     IDoWork<? extends AbstractKey, ? extends AbstractClass> instance = 
       WorkFactory.getInstance().obtainInstance(a); 
     instance.obtain(a, c); 
    } 
} 

public class WorkFactory { 

    private static final WorkFactory INSTANCE = new WorkFactory(); 

    public static WorkFactory getInstance() { 
     return INSTANCE; 
    } 

    public IDoWork<? extends AbstractKey, ? extends AbstractClass> obtainInstance(AbstractKey key){ 
     if(key instanceof KeyA){ 
      return DoWorkA.getInstance(); 
     } 
     throw new IllegalArgumentException("Case not handled"); 
    } 

} 

:

KeyA a = new KeyA(); 
ConcreteA c = new ConcreteA(); 
IDoWork<? extends AbstractKey, ? extends AbstractClass> instance = WorkFactory.getInstance().obtainInstance(a); 
instance.obtain(a, c); 

이 라인은 컴파일되지 않습니다 :

instance.obtain(a, c); 

은 Java generics의 특성 때문에 발생합니다. 다음 오류가 발생합니다.

The method obtain(capture#3-of ? extends AbstractKey, capture#4-of ? extends AbstractClass) in the type IDoWork is not applicable for the arguments (KeyA, ConcreteA)

다른 방법이 있습니까? 내가 IDoWork에서 유형 매개 변수를 제거하면

IDoWork<? extends AbstractKey, ? extends AbstractClass> instance =... 

의 유형 매개 변수를 생략하면 ... 그것은 작동하지만 경고를 얻을. 그 문제를 해결할 수있는 방법이 있습니까? 내가 인터페이스에서 형식 매개 변수를 제거 할 수 있고 그 문제를 해결할 수 있지만 캐스팅 할 필요가 없기 위해 제네릭을 가지고 편리하다는 것을 알면 코드에 선명도를 가져다 준다. 각 클래스 사용. . Depencendy 주입은 내가에있어 코드베이스에서 사용할 수 없습니다이기 때문에 작동 뭔가를 질문에서

+1

당신은 사용할 수 없습니다 : 'IDoWork 예 = WorkFactory.getInstance() obtainInstance (A)'.? 'WorkFactory'의 코드는 무엇입니까 - 제네릭 형식 인수로 무엇을 바인딩합니까? –

+0

방금 ​​WorkFactory 클래스를 추가했습니다. 공장은 키 값이 아닌 –

답변

0

이지만, 매우 최적되지 않습니다 :

당신은 당신의 WorkFactory 이런 식으로 정의하는 경우 :

public class WorkFactory { 
    private static final WorkFactory INSTANCE = new WorkFactory(); 
    public static WorkFactory getInstance() { 
     return INSTANCE; 
    } 

    @SuppressWarnings("unchecked") 
    public <K extends AbstractKey, V extends AbstractClass> IDoWork<K, V> obtainInstance(K key, V val) { 
     if (key instanceof KeyA) { 
      return (IDoWork<K, V>) DoWorkA.getInstance(); 
     } 
     throw new IllegalArgumentException("Case not handled"); 
    } 

} 

다음의 주요 방법은 정상적으로 작동합니다 : 내가 제대로 유형을 추론, 키와 발을 취할 obtainInstance을 변경 한

public static void main(String[] args){ 
     KeyA a = new KeyA(); 
     ConcreteA c = new ConcreteA(); 
     IDoWork<KeyA, ConcreteA> instance = WorkFactory.getInstance().obtainInstance(a, c); 
     instance.obtain(a, c); 
} 

.

+0

덕분에 경고를 제공합니다. IDoWork 인스턴스를 = WorkFactory.getInstance() obtainInstance (A); @SuppressWarnings없이이 경고를 제거하는 방법을 알고 싶습니다. 그것은 아직도 당신이 서명에서 값을 제거하는 경우에도 작동합니다 –

+0

folllowing 코드가 작동을 사용하지만해야 당신의 답변을하지만 내 경우에는 감사 –

+0

, 그것은 좌 –