2016-12-15 1 views
0

비교적 간단한 코드 블록을보고 데이터베이스에 도달하고 그 결과를 LinkedList로 반환했습니다. SQL이 주입되어야한다는 것은 명백한 것처럼 보였지만, LinkedList 역시 불필요한 종속성이었습니다. 다음과 같이java : 종속성 삽입을위한 인수로 클래스 전달

단순화 된 버전입니다 :

public List<String> getStrings() { 
    //Hard coded reference to LinkedList 
    List<String> tmp = new LinkedList<String>(); 
    tmp.add("foo"); 
    return tmp; 
} 

내가 나를 런타임에 목록 구현을 지정할 수 있도록 그것을 다시 작성했습니다.

getStrings (LinkedList.class)를 사용하여 getStrings (클래스 < List> listType)를 호출하면 적용 할 수없는 메서드에 대한 오류가 발생합니다. 확인 다음 작품>

public List getStrings(Class<? extends List> listType) throws InstantiationException, IllegalAccessException { 
    List tmp = listType.newInstance(); 
    tmp.add("foo"); 
    return tmp; 
} 

public void caller() throws InstantiationException, IllegalAccessException { 
    List stringList = getStrings(LinkedList.class); 
} 

그러나 모든 참조를 나열하고 정말 목록 < 문자열해야하기 때문에 tmp를 유형의 안전에 대해 불평하고있다.

getStrings()에서 확인 일반 작품을 추가 :

public List<String> getStrings(Class<? extends List<String>> listType) throws InstantiationException, IllegalAccessException { 
    List<String> tmp = listType.newInstance(); 
    tmp.add("foo"); 
    return tmp; 
} 

을하지만, 업데이트 된 호출은 전혀 컴파일되지 않습니다 :

getStrings(LinkedList<String>.class); 

다음 작품을하지만, 나에게 검사되지 않은 캐스트 경고를 제공 :

getStrings((Class<? extends List<String>>) LinkedList.class); 

올바른 방법 (tm)이 있습니까?

답변

2

당신이 발견 한 것처럼, 런타임 리플렉션은 컴파일 타임 제네릭과 잘 섞이지 않습니다. Java 8을 사용하는 경우 훨씬 더 안전하고 안전한 방법을 제안합니다.

public List<String> getStrings(Supplier<List<String>> listSupplier) { 
    List<String> tmp = listSupplier.get(); 
    tmp.add("foo"); 
    return tmp; 
} 

public void caller() { 
    List<String> stringList = getStrings(LinkedList::new); 
}