본문 바로가기

별걸다하는 IT/프로그래밍언어

[자바에러]NumberFormatException (string input에러, 자료형 불일치 에러)

 

에러코드를 정확히 읽는 습관 또한 매우 중요하니까 오늘은 발생한 에러코드가 어떤 것을 의미하는지 살펴보도록 합시다.

오늘 소개할 에러코드는 흔하게 접할 수 있는 NumberFormatException입니다.

이 에러는 문자열 string을 숫자 타입(정수나 실수 등)으로 변환하려고 하는데 그 형식이 잘못되었을 때 나타나는 오류입니다. 리털럴리, 말 그대로 'Number: 수 Format: 형식 Exception: 오류'예요

쉽게 말해 잘못된 형변환으로 자료형 불일치 경우에 발생하는 에러
-NumberFormatException

무엇을 의미하는 지 인지하고 있으면 에러를 잡는 건 어렵지 않겠지만 조금 더 수월하고 빠른 캐치를 위해 대표적인 발생 상황을 살펴볼게요

 

발생 원인 요약

출처: https://www.java67.com/2016/10/10-reasons-of-javalangnumberformatexception-in-java-solution.html

1. 문자를 Integer.paresInt()를 이용해 숫자로 변경을 시도하는 경우입니다.

(Double.parseDouble(), Float.parseFloat() 등등 유사 함수도 포함이예요)

       1-1 String안의 내용이 잘못 넣어졌을 경우, 즉 변환이 불가한 경우가 있을 수 있고

        1-2 전달받은 매개변수의 값이 NULL이거나 매개변수 값을 가져오지 못할 때 해당 에러가 발생합니다.

 

2. int의 최대 값을 벗어난 수를 int로 변경하는 경우, 얘도 마찬가지로 int만 해당하는 것은 아니고 오버플로우 되는 상황을 통틀어 말하는 겁니다.

CODE EXAMPLES

예시를 들어볼까요?

여러 분들도 코드를 보면서 어디서 에러가 떴는지 한 번 찾아보세요.

 

1. 비슷한 글자 헷갈려서 잘못넣는 경우가 은근 꽤 있다. 

import java.io.IOException;
public class Main {
	 public static void main(String[] args) throws IOException{
		String phoneIDD ="O82";
		String phoneNumber =phoneIDD+ "01012345678";
		int phone = Integer.parseInt(phoneNumber);
	 }
}

이 코드에서 오류 찾기 어려울 수도 있는데요..ㅎㅎㅎㅎㅎ 약간 말장난이라..?

phoneIDD의 String의 앞에 082가 아니라 O82이기 때문에 변환오류가 뜬 것입니다.

즉 숫자로 변환할 수 없는 알파벳 O가 껴있기 때문이죠. 왜 오류가 떴는지 도저히 모르겠을 때는 문자열 부문을 다시 작성해보는게 빠르게 오류를 잡는 방법이 될 수 있어요.

 

 

2. 공백/문자열

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
	 public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int num = Integer.parseInt(br.readLine());
		int[] arr = new int[num];
	    for(int i=0; i<num; i++) {
	    	arr[i] = Integer.parseInt(br.readLine());
	    }
	 }
}

답을 찾으셨나요? Scanner의 nextInt()를 습관적으로 쓰다가 readLine()을 마치 한 단어를 읽어들이는 것처럼 사용해서 일어난 실수입니다. readLine()은 한줄을 읽기 때문에 "8"이 들어가는게 아니라 "0 8 2 4"이런 공백을 포함한 문자열을 읽어들이니까요 ㅎ 이 여러 숫자가 포함된 문자열을 하나의 int로 변경하려니까 오류가 난겁니다. 즉 이것 또한 내부 변환하고자 하는 문자열이 잘못되어 있는 케이스인거죠

 

다음과 같은 원리로 하나의 숫자만 입력받았어도 "8"이 아니라 "8 " 이렇게 띄어쓰기가 같이 들어가버리면 해당 에러가 발생합니다. 따라서 Integer.parseInt("") 도 해당 에러를 발생시킵니다.

 

3. 웹 상에서 파라미터를 넘겨받았을 때?

int boardId = Integer.parseInt(request.getParameter("boardId"));

//html 
<input type="text" name="boardId" id="boardId" value="${param.boardID}">

잘 보면 파라미터로 boardID를 전달했는데 받는 부문은 boardId 마지막 'd'스펠링(대소문자)이 잘못되었죠? 이와 같이 매개변수명을 일치시켜주지 않아 값을 전달받지 못할 때에도 해당 에러가 발생합니다.

 

4. 오버플로우

public class Main {
	 public static void main(String[] args) {
		String binary ="11111111101010100111011000111110";
		int num = Integer.parseInt(binary, 2);
		System.out.println(num);
	 }
}

이진수 문자열을 10진수 정수로 변환하는 코드입니다. 왜 NumberFormatException이 떴을까요?

해당 이진수가 int가 가질 수 있는 범위값보다 크기 때문에 오버플로우 에러가 뜬거예요. 항상 어느 업종이던 오버플로우는 신경써줘야함.

public class Main {
	 public static void main(String[] args) {
		String binary ="11111111101010100111011000111110";
		long num = Long.parseLong(binary, 2);
		System.out.println("변환한 값: "+ num);
		System.out.println("int가 가질 수 있는 값: "+Integer.MAX_VALUE);
	 }
}

이와 같이 확인해볼 수 있습니다.

 

5. 문자열 앞뒤에 공백이 들어올 경우

" 123"이런 문자열 될 거 같죠? 근데 이것때메 해당 오류가 날 수 있습니다. "123 "도 마찬가지예요.

 

정보 공유에 활력이 되는 광고보답/댓글/좋아요♥ 

여러분은 어떤 상황에서 해당 에러를 접했나요?! 다른 상황이 있으시다면 경험담 공유도 도움이 됩니다.

질의 응답, 조언 또한 환영합니다 :) 그럼 다음 포스팅에서 또 봐요~!