2012-06-14 2 views
0

Java 응용 프로그램에서 이상한 동작이 표시되고 솔루션을 찾는 데 문제가 있습니다.LinkedHashMap을 읽을 때 Java가 String에서 Integer로 자동 캐스팅되는 이유

이 코드 조각은 키와 값이 모두 String이고 텍스트 파일에 쓰기위한 LinkedHashMap의 내용을 사용합니다. configWriterPrintWriter입니다.

for (Map.Entry<String, String> entry : configMap.entireSet()) { 

    configWriter.println(entry.getKey() + "=" + entry.getValue()); 
} 

지도 선언했다 :

LinkedHashMap<String, String> configMap = new LinkedHashMap<String, String>(); 

는 그것은 Scanner 클래스를 사용하여 텍스트 파일에서 토큰을 읽어 채워집니다. 지도에있는 값의

하나는 숫자 만 (정수)를 포함하는 String이지만, 루프가이 값에 도달 할 때, 당신이 Integer에서 String에 캐스트 할 수없는 말하는 ClassCastException가 발생합니다. 이것은 완벽하게 이해할 수 있지만 값의 유형은 String입니다.

Java가이 값을 String으로 유지하도록 강제 할 수 있습니까?

+9

'configMap' 선언을 표시 할 수 있습니까? 이것은 rawtypes가 어딘가에서 사용 된 것처럼 들리며 맵은 실제로 모든 'String'을 포함하지 않습니다. –

+3

또한 스택 추적이 도움이 될 수 있습니다. –

+1

질문을 편집하십시오. 정보를 주석으로 추가하지 마십시오. –

답변

7

원시 유형이 어딘가에서 사용되고 있고 거의 Integer이지도에 몰래 빠져 있다는 것이 거의 확실합니다.

Integer지도에 삽입지고 함께 configMap의 초기화를 대체하는 것입니다 확인하는 가장 쉬운 방법 String 이외의 뭔가에 삽입됩니다 경우 실제로 예외가 발생합니다

Map<String, String> configMap = Collections.checkedMap(
    new LinkedHashMap<String, String>(), String.class, String.class); 

지도. 개인적으로 프로덕션 코드에서 사용하지는 않겠지 만, 아마도 이것은 버그를 "피우는"가장 간단한 방법 일 것입니다. Integer이 정확히 어디에 삽입되는지에 대한 예외 및 스택 추적을 받게됩니다.

유형 삭제로 제네릭을 구현하는 방법은 실제로 이 없으므로 String 값이지도에 삽입되지 않도록합니다. 컴파일러는이를 방지하기 위해 노력하지만 rawtype과 레거시 코드가이를 피할 수 있습니다. 그래도 Collections.checkedMap을 사용하면 문제가 발생합니다.

+0

'Collections.checkedMap'을 원하셨습니까? –

+0

... 예. 그래, 내가 했어. 뇌에 너무 많은 구아바. –

2

Louis Wasserman이 문제의 가능한 원인을 설명했습니다.

난 그냥 당신의 질문에 당신의 사고에 몇 가지 결함이 있다는 것을 지적하고 싶습니다.

왜 자바가 자동으로 당신은 IntegerString에서 캐스팅 할 수없는,

최초의 LinkedHashMap

을 읽을 때 정수로 문자열에서 캐스팅입니다. 자바 참조 유형을 사용하면 객체가 해당 유형의 인스턴스이거나 해당 유형의 하위 유형 인 경우에만 객체를 유형으로 형변환 할 수 있습니다. String 유형은 Integer의 하위 유형이 아니므로 JVM 의 조작 상 의미는 그러한 캐스트를은 금지합니다. 이렇게하려고하는 컴파일 가능한 코드를 작성하면 런타임 예외가 발생합니다.

둘째, LinkedHashMap 아무것도 ... 또는 당신이에 말하지 않고 IntegerString에서 요소/키/값 인스턴스를 변환 할 다른 컬렉션 클래스가 없다. Well-behaved (Java) API는 그런 종류의 일을하지 않습니다.

루이의 진단으로 돌아갑니다. 코드 (예 : 코드)가 Integer 개체를 값으로 추가했습니다. 원시 형식을 사용하거나 "확인되지 않은 변환"경고를 표시하거나 무시하는 경우 발생할 수있는 일입니다.