제 스프링 애플리케이션 컨텍스트 파일에는 다음과 같은 내용이 있습니다:
<util:map id="someMap" map-class="java.util.HashMap" key-type="java.lang.String" value-type="java.lang.String">
<entry key="some_key" value="some value" />
<entry key="some_key_2" value="some value" />
</util:map>
자바 클래스에서 구현은 다음과 같습니다:
private Map<String, String> someMap = new HashMap<String, String>();
someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
이클립스에서는 다음과 같은 경고가 표시됩니다:
유형 안전: 체크되지 않은 객체에서 해시맵으로 형변환<문자열,문자열>.
내가 뭘 잘못했나요? 이 문제를 어떻게 해결하나요?
우선, 새로운 '해시맵' 생성 호출로 메모리를 낭비하고 있습니다. 두 번째 줄은 생성된 해시맵에 대한 참조를 완전히 무시하고 가비지 콜렉터에서 사용할 수 있도록 합니다. 그러니 그렇게 하지 말고 사용하세요:
private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
둘째, 컴파일러는 객체가 해시맵
인지 확인하지 않고 해시맵
으로 캐스팅했다고 불평합니다. 하지만 그렇게 한다고 해도:
if(getApplicationContext().getBean("someMap") instanceof HashMap) {
private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
}
이렇게 해도 여전히 이 경고가 표시될 것입니다. 문제는 getBean
이 Object
를 반환하므로 유형이 무엇인지 알 수 없다는 것입니다. 이를 HashMap
으로 직접 변환하면 두 번째 경우에는 문제가 발생하지 않습니다(첫 번째 경우에는 경고가 없을 수도 있습니다. Java 컴파일러가 Java 5의 경고에 대해 얼마나 현학적인지 잘 모르겠습니다). 그러나 해시맵, 문자열, 문자열
로 변환하고 있습니다.
해시맵은 실제로는 객체를 키로 사용하고 객체를 값으로 갖는 맵, 즉 HashMap<Object, Object>
입니다. 따라서 반환되는 비일반 표현은 어떤 객체든 가질 수 있기 때문에 HashMap<Date, Calendar<
를 가질 수 있기 때문에 빈을 가져올 때 HashMap<String, String<
로 표현될 수 있다고 보장할 수 없습니다.
코드가 컴파일되고 String value = map.get("thisString");
을 오류 없이 실행할 수 있다면 이 경고에 대해 걱정하지 않아도 됩니다. 그러나 맵이 문자열 값에 대한 문자열 키로 완전히 구성되지 않은 경우, 이 경우 제네릭이 이를 차단할 수 없기 때문에 런타임에 ClassCastException
이 발생합니다.
위의 메시지를 나탸내도록 목록에 따라 차별화된 ',' 와 'List< Object> List< 就不可能拥有 간에,,', '또는' List< String> Integer>.
List<String> strList = (List<String>) someFunction();
String s = strList.get(0);
다음:
List<?> strList = (List<?>) someFunction();
String s = (String) strList.get(0);
설명: 첫번째 유형 변환 객체인지 있는지 확인 없이 바뀌엇어요 돌보는 유형에 대한 내 유보됨 (이후 우리는 내부 유형은상위 dell. 목록에서 확인할 수 없는 수준). 이제 이 목록에 포함된 것을 알고 있기 때문에 필요한 두 번째 변환은 컴파일러에만 일종의 객체에는. 이 목록의 각 개체의 유형을 확인하기 때문에 액세스됩니다.
경고는 그냥 경고입니다. 경고입니다. 경고는 때때로 관련이 없는 경우도 있지만 그렇지 않은 경우도 있습니다. 컴파일러가 문제가 될 수 있다고 생각하지만 문제가 아닐 수도 있는 것에 주의를 환기시키는 데 사용됩니다.
캐스트의 경우, 이 경우 항상 경고를 표시합니다. 특정 형 변환이 안전하다고 확신하는 경우 해당 줄 바로 앞에 다음과 같은 주석(구문은 잘 모르겠습니다)을 추가하는 것이 좋습니다:
@SuppressWarnings (value="unchecked")
이 메시지가 표시되는 이유는 getBean이 객체 참조를 반환하고 이를 올바른 유형으로 캐스팅하고 있기 때문입니다. Java 1.5는 경고를 표시합니다. 이는 이와 같이 작동하는 코드에 Java 1.5 이상을 사용하는 경우의 특성입니다. Spring에는 유형 안전 버전이 있습니다.
someMap=getApplicationContext().getBean<HashMap<String, String>>("someMap");
을 지원해야 합니다.
진짜 원한다면 경고를 한 가지만 없앨 수 있는 일반 클래스 (class 에서 연장시킵니다 만들 수 없습니다.
예를 들어, re 사용하려는 you& # 39.
private Map<String, String> someMap = new HashMap<String, String>();
이 같은 새로운 클래스를 작성할 수 있습니다.
public class StringMap extends HashMap<String, String>()
{
// Override constructors
}
사용할 때 단순화표현
someMap = (StringMap) getApplicationContext().getBean("someMap");
컴파일러는 높여줍니까 알고 있을 것입니다. (더 이상 일반) 유형은 경고야 이러한 종류의 패를 주장할 수 없는 경우도 있습니다 이 가장 적합한 솔루션을 일부 권능은하나님께 목적이 아니라 일반 클래스뿐만 you& # 39 에서 동일한 코드 재사용, re still 모든 일반 클래스, you& # 39 선언, re 그냥 컴파일 타임에 운영까지도 종류를 사용할 수 있습니다.
또 다른 솔루션을 찾을 수 있다면, 교도관님도요 캐스팅 같은 객체에는 많이유 진실이며당신이 don& 코드에서 # 39, 가마 (unchecked" ";) '와' @SupressWarnings 싶지 않다, 약간만이라도 만드는 데 사용하는 방법을 주석. 이렇게 you& # 39 의 캐스팅, 중앙 집중식으로 가능성을 줄일 수 있기를 바랍니다, re 오류:.
@SuppressWarnings("unchecked")
public static List<String> getFooStrings(Map<String, List<String>> ctx) {
return (List<String>) ctx.get("foos");
}
'Map<, 문자열, Object>. 미린푸스 = (Map<, 문자열, Object>) '미리퀘스트리제 ();
>. 해결하십시오
객체 유형에 대해서는 언급하지 않고 새로운 것을 만들 수 있기 때문에 매개변수입니다 매핑해야 객체에는 목록 내의 유보됨 미채택 있다.
'Map< >;?? 트럼프마프 = (Map< >??;;) '미리퀘스트리제 ();
Map<String, Object> myInput=new HashMap<>(myInputObj.size());
for(Map.Entry<?, ?> entry :myInputObj.entrySet()){
myInput.put((String)entry.getKey(),entry.getValue());
}
>. 내가 뭘 그래? 이 문제를 어떻게 해결합니까? >.
여기.
'Map<, 문자열, String>. 섬마프 = (Map<, 문자열, String>), '지그레빈 게테플리카션콘테스트 () (someMap" ";)
우리가 일반적으로 사용하는 기존 방법 # 39, 그 이후 't want to use don& 되돌려줍니다 객체에는':
Object getBean(String name) throws BeansException;
방법 좀 얻을 수 있는 콩 볶아 팩터리의 (backup-to-disk 싱글턴) / (backup-to-disk 프로토타입) 을 만들 수 있다.
5 396 {{{000}}}
이를 사용하여 다음과 같은
Map<String,String> someMap = app.getBean(Map.class,"someMap");
하지만 아직도 가지고 있지 않은 모든 개체는 매핑해야 '경고' 는 이후 컴파일하십시오 변환, 문자열, 꼭 그렇지만은 않은 것 같다 ',' 객체에는 Map< String>.
하지만 '< T>; T 제빈 (String name, Class< T>; 레키레트리프), 콩 등 일반 컬렉션 '에 일반 클래스뿐만 콩스엑스티온 던지는 충분하지 않을 만큼 둘 이상의 매개 변수로 하는 클래스를 지정할 수 있습니다. the collection 유형 및 해당 일반 유형 (s).
이런 상황을 직접 사용할 수 있지만, 일반적으로 더 좋은 것은 '투자' 방법을 사용하면 프레임워크입니다 외곽진입 콩파스토리 의 콩.
이 빈 선언:
@Configuration
public class MyConfiguration{
@Bean
public Map<String, String> someMap() {
Map<String, String> someMap = new HashMap();
someMap.put("some_key", "some value");
someMap.put("some_key_2", "some value");
return someMap;
}
}
이 빈 사출:
@Autowired
@Qualifier("someMap")
Map<String, String> someMap;