문제

스프링 응용 프로그램 컨텍스트 파일에는 다음과 같은 것이 있습니다.

<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>

Java 클래스에서는 구현이 다음과 같습니다.

private Map<String, String> someMap = new HashMap<String, String>();
someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");

일식에서는 다음과 같은 경고를 봅니다.

타입 안전 : 객체에서 해시 맵으로 확인되지 않은 캐스트

내가 뭘 잘못 했어? 문제를 어떻게 해결합니까?

도움이 되었습니까?

해결책

글쎄, 우선, 당신은 새로운 것과 함께 기억을 낭비하고 있습니다 HashMap 창조 전화. 두 번째 줄은이 생성 된 해시 맵에 대한 참조를 완전히 무시하고 쓰레기 수집가가 이용할 수있게합니다. 그러니 그렇게하지 말고 사용하십시오.

private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");

둘째, 컴파일러는 당신이 객체를 HashMap 그것이 있는지 확인하지 않고 HashMap. 그러나 당신이해야하더라도 :

if(getApplicationContext().getBean("someMap") instanceof HashMap) {
    private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
}

당신은 아마도 여전히이 경고를받을 것입니다. 문제는, getBean 보고 Object, 그래서 유형이 무엇인지 알 수 없습니다. 그것을 변환합니다 HashMap 두 번째 사례에 직접 문제를 일으키지 않을 것입니다 (아마도 첫 번째 경우에는 경고가 없을 것입니다. Java Compiler가 Java 5에 대한 경고로 얼마나 pedantic인지 잘 모르겠습니다). 그러나, 당신은 그것을 a로 변환하고 있습니다 HashMap<String, String>.

해시 맵은 실제로 객체를 키로 가져 가서 객체를 값으로 사용하는 맵입니다. HashMap<Object, Object> 당신이 할 경우. 따라서 콩을 얻을 때 그것이 HashMap<String, String> 당신은 가질 수 있기 때문입니다 HashMap<Date, Calendar> 반환 된 비 게 릭 표현은 객체를 가질 수 있기 때문입니다.

코드가 컴파일되고 실행할 수있는 경우 String value = map.get("thisString"); 오류가 없으면이 경고에 대해 걱정하지 마십시오. 그러나 맵이 문자열 값에 대한 문자열 키가 아니라면 ClassCastException 런타임에 제네릭 이이 경우에이를 막을 수 없기 때문에.

다른 팁

문제는 캐스트가 런타임 점검이라는 것입니다. 그러나 유형 삭제로 인해 런타임에 실제로는 HashMap<String,String> 그리고 HashMap<Foo,Bar> 다른 사람을 위해 Foo 그리고 Bar.

사용 @SuppressWarnings("unchecked") 그리고 코를 잡아라. 아, 그리고 자바의 재 구선 제네릭 캠페인 :)

위의 메시지에서 알 수 있듯이 목록은 List<Object> 그리고 a List<String> 또는 List<Integer>.

비슷한 문제에 대한이 오류 메시지를 해결했습니다.

List<String> strList = (List<String>) someFunction();
String s = strList.get(0);

다음과 함께 :

List<?> strList = (List<?>) someFunction();
String s = (String) strList.get(0);

설명 : 첫 번째 유형 변환은 객체가 내부에있는 유형에 대한 관심이없는 목록임을 확인합니다 (목록 레벨에서 내부 유형을 확인할 수 없기 때문에). 컴파일러에 목록에 일종의 객체가 포함되어 있다는 것을 알고 있기 때문에 두 번째 변환이 필요합니다. 이것은 액세스 할 때 목록의 각 객체의 유형을 확인합니다.

경고는 바로 그 것입니다. 경고. 때로는 경고가 관련이 없으며 때로는 그렇지 않습니다. 그들은 컴파일러가 문제가 될 수 있다고 생각하지만 그렇지 않을 수도있는 것에주의를 기울이는 데 사용됩니다.

캐스트의 경우,이 경우 항상 경고를 줄 것입니다. 특정 캐스트가 안전 할 것이라고 확신한다면, 라인 직전에 이와 같은 주석을 추가하는 것을 고려해야합니다 (구문은 확실하지 않음).

@SuppressWarnings (value="unchecked")

Getbean이 객체 참조를 반환하고 올바른 유형으로 캐스팅하기 때문에이 메시지를 받고 있습니다. Java 1.5는 경고를 제공합니다. 이것이 바로 Java 1.5 이상을 사용하는 특성입니다. Spring에는 TypeSafe 버전이 있습니다

someMap=getApplicationContext().getBean<HashMap<String, String>>("someMap");

TODO 목록에.

당신이 정말로 경고를 제거하고 싶다면, 당신이 할 수있는 한 가지는 일반 클래스에서 확장되는 수업을 만드는 것입니다.

예를 들어, 사용하려는 경우

private Map<String, String> someMap = new HashMap<String, String>();

그런 새로운 클래스를 만들 수 있습니다

public class StringMap extends HashMap<String, String>()
{
    // Override constructors
}

그런 다음 사용할 때

someMap = (StringMap) getApplicationContext().getBean("someMap");

컴파일러는 더 이상 일반적인 유형이 무엇인지 알고 있으며 경고가 없습니다. 이것은 항상 완벽한 솔루션이 아닐 수도 있습니다. 어떤 사람들은 이런 종류의 패배를 일반 클래스의 목적을 논쟁 할 수도 있지만, 여전히 일반 클래스에서 동일한 코드를 모두 재사용하고 있습니다. 당신은 사용하고 싶습니다.

또 다른 해결책, 동일한 개체를 많이 캐스팅하고 코드를 쓰고 싶지 않으면 @SupressWarnings("unchecked"), 주석으로 메소드를 만드는 것입니다. 이렇게하면 캐스트를 중앙 집중화하고 오류 가능성을 줄이기를 희망합니다.

@SuppressWarnings("unchecked")
public static List<String> getFooStrings(Map<String, List<String>> ctx) {
    return (List<String>) ctx.get("foos");
}

아래 코드는 유형 안전 경고를 일으 킵니다

Map<String, Object> myInput = (Map<String, Object>) myRequest.get();

해결 방법

목록 내에있는 객체 유형이 확인되지 않기 때문에 매개 변수를 언급하지 않고 새 맵 객체를 만듭니다.

1 단계: 새 임시지도를 만듭니다

Map<?, ?> tempMap = (Map<?, ?>) myRequest.get();

2 단계: 메인 맵을 인스턴스화하십시오

Map<String, Object> myInput=new HashMap<>(myInputObj.size());

3 단계 : : 임시 맵을 반복하고 값을 기본지도로 설정합니다.

 for(Map.Entry<?, ?> entry :myInputObj.entrySet()){
        myInput.put((String)entry.getKey(),entry.getValue()); 
    }

확인되지 않은 경고를 피하기위한 해결책 :

class MyMap extends HashMap<String, String> {};
someMap = (MyMap)getApplicationContext().getBean("someMap");
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top