2013-11-01 1 views
5

프로젝트에서 이론적으로 (지원되는) 모든 유형의 관리자를 만들 수있는 팩토리 클래스를 만들었습니다. 관리자와 상호 작용하면 주어진 유형의 특정 속성을 변경할 수 있습니다. 필자가 직면하고있는 문제는 제네릭 형식의 관리자를 만들려고 할 때 컴파일러가 내 희망과 꿈을 부수는 것입니다.자바 : 와일드 카드 형식이 일치하지 않아 컴파일 오류가 발생합니다

다음 코드는 내가 작업하고있는 버전의 일부입니다. 내 'test3Manager'를 만들려고 시도하는 줄이 컴파일되지 않고 이것이 왜 그런지 이해하려고합니다. 그 아래의 줄은 '회피책'을 보여 주며 나는 피하려고합니다.

import java.util.List; 

    public class GenTest { 
     public static void main(String[] args) { 
      String test1 = ""; 
      IRandomType<String> test2 = null; 
      IAnotherRandomType<?> test3 = null; 

      IManager<String> test1Manager = Factory.createManager(test1); 
      IManager<IRandomType<String>> test2Manager = Factory.createManager(test2); 
      IManager<IAnotherRandomType<?>> test3Manager = Factory.createManager(test3); // Doesn't compile. Why? 

      // Work around? 
      IManager<?> test3ManagerTmp = Factory.createManager(test3); 
      IManager<IAnotherRandomType<?>> test3Manager2 = (IManager<IAnotherRandomType<?>>) test3ManagerTmp; 
     } 

     public interface IRandomType<T> {} 
     public interface IAnotherRandomType<T> {} 
     public interface IManager<T> {} 

     public static class Factory { 
      public static <T> IManager<T> createManager(T object) { 
       return null; 
      } 
     } 
    } 

정확한 컴파일 오류 메시지는 다음과 같습니다

Type mismatch: cannot convert from GenTest.IManager<GenTest.IAnotherRandomType<capture#1-of ?>> to GenTest.IManager<GenTest.IAnotherRandomType<?>> 

비슷한 질문을하기 전에 요청을받은 (아래 참조) 그러나 나는이 질문이 그것들의 복제본으로 간주되는지는 모른다. 나는이 질문들에 대한 대답을 나의 것으로 추측하는 데 어려움을 겪고 있기 때문에 이것을 진술한다. 나는 누군가 제네릭 사용에 대해 내가 잘못하고있는 것을 분명히 할 수 있기를 바라고 있습니다. SO에

관련 질문은 다음

답변

3

사용 : 이것은 컴파일러의 형식 유추 단지 경우에 떨어지고

IManager<IAnotherRandomType<?>> test3Manager = 
     Factory.<IAnotherRandomType<?>>createManager(test3); 

그것의 얼굴, 그래서 명시 적으로 형식을 제공해야합니다 ent에 T을 입력하십시오.

더 기술적으로 :

test3?와일드 카드 캡처 인 유형 IAnotherRandomType<?>,이 선언됩니다 - 일부 특정 알 수없는 유형을 나타내는 하나의 사용 유형 매개 변수의 종류. 컴파일러가 capture#1-of ?이라고 말하면서 컴파일러가 참조하는 것입니다. test3createManager에 전달하면 은 IAnotherRandomType<capture#1-of ?>으로 유추됩니다.

한편, test3Manager중첩 된 와일드 카드이있는 유형 IManager<IAnotherRandomType<?>>,이 선언됩니다 - 그것은 형식 매개 변수처럼 행동하지 않습니다 오히려 모든 종류의을 나타냅니다.

제네릭 aren't covariant이므로 컴파일러는 IManager<IAnotherRandomType<capture#1-of ?>>에서 IManager<IAnotherRandomType<?>>으로 변환 할 수 없습니다.중첩 된 와일드 카드에

더 읽기 :

+0

+1 그냥 하나의 편집 - T'는'IAnotherRandomType <캡처 # 1로 추정됩니다' ? of #? of? of #? –

+0

여기에 공분산이 실제로 관련되어 있습니까? '# 1 캡쳐'및 '?'관련이 없습니까? – mpartel

+0

@RohitJain 멋진 catch - 고정. –

관련 문제