[자바]java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer (부제: 형변환은 항상 신경 좀 씁시다.) + 이외에 다른 자바 형변환 정리
여느때와 같은 평화로운 근무시간.
파라미터 하나가 추가되어 수정해달라는 요청을 받고 평소와 같이 수정을 마쳤다.
코드 한 줄 바꾼 것이고 파라미터 명만 신경쓰면 당연히 오류가 나지 않을 것이라 자신하며 배포를 했으나 이게 웬 걸 에러가 터져버렸다.
이제는 익숙해진 에러 문구.
String인데 왜 int로 변경하려고 하느냐 어리석은 녀석아 하는 메시지이다.
JS처럼 저절로 형변환이 되면 좋으련만 JAVA는 이래저래 손이 많이 가는 친구다.
형변환이란?
서로 다른 타입간의 연산을 수행할 때 타입을 일치시키기 위해 변수나 리터럴의 타입을 다른 타입으로 변환하는 것.
String, int 형변환하는 법
- String to int
String ex_str = "123";
int ex_int = Integer.parseInt(ex_str);
- int to String
int ex_int = 123;
String ex_str = Integer.toString(ex_int);
or
String ex_str = String.valueOf(ex_int);
or
String ex_str = ex_int + "";
형변환은 이런식으로 해주면 된다.
가격과 관련된 파라미터라서 당연히 int로 받을 것이라 생각했는데 알고보니 '90,000' 이런 식으로 가격 포맷이 된 상태로 값이 오는 녀석이었다.
당연히 String 형태였고.
내가 처음에 처리해 준 것은
int price = jsonMap.get("price_format") == null ? 0 : (int) jsonMap.get("price_format");
이런식으로 값을 받아서 null이면 0을 null이 아니면 price_format의 값을 가져오는 것이었다.
그런데 price_format이 String으로 넘어오고 있는데 저런 식으로 형변환을 해주니 위의 에러가 뜨는 것이었다.
'에러가 나지 않게' 신경써서 처리할 부분은 총 세가지였다.
1. null이거나 빈 값이 아닐 경우에만 값을 넣어주도록
2.String to int로 형변환을 시켜 int로 값을 받도록(이건 프로젝트 내에서 가격을 받는 함수가 String을 Input하도록 설정되어 있어서 해준 것. 개인 프로젝트라면 굳이 할 필요 없다.)
3.가격 포맷 때문에 들어간 쉼표(,)를 제거하도록
if(!"".equals(price_format) && price_format!=null) {
jsonMap.put("price_format", Integer.parseInt( price_format.replaceAll(",", "") ));
}
그리고 이런 식으로 수정했다.
String to int 형변환으로 Integer.parseInt를 사용했고 쉼표는 replaceAll() 함수를 이용했다.
까다로운 부분은 아닌데 꼭 잊을만 하면 한번씩 놓쳐서 에러를 뱉는 녀석이니 체크하고 넘어가자.
String int 외에도 형변환하는 법도 짚고 넘어가자.
이 뒤로는 그냥 형변환 헷갈릴때 내가 와서 보려고 정리한 메모다.
변환 | 수식 | 결과 |
int to char | (char)65 | 'A' |
char to int | (int)A | 65 |
float to int | (int)1.6f | 1 |
int to float | (float)10 | 10.0f |
자동형 형변환(암묵적 형변환)
- 데이터 손실이 없는 한 자동으로 형변환됨.
byte(1) > short(2) > char(2) > int(4) > long(8) > float(4) > double(8)
조건이 붙긴 하지만 자바도 자동 형변환이 되는지는 몰랐다.
변환 | 수식 |
String to double | Double.valueOf(str) |
String to float | Float.valueOf(str) |
String to long | Long.parseLoing(str) |
String to short | Short.parseShort(str) |
정수 <--> 실수 의 형변환은 '(int)' 를 앞에 붙혀준다.(내가 잘못해서 넣은 케이스)
char은 int와 연산이 가능하다.
이 아스키코드 표를 통해 나오는 숫자를 통해 별도의 형변환없이 char는 int와 연산이 가능하다.
char a = 97;
int b = a + 100;
System.out.println(b) //197