본문 바로가기
[ Developer ]/Core Java

[Java] 예외 처리 (try ~ catch)

by 김현섭. 2016. 2. 22.
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
예외 처리 (try ~ catch)
예외란 프로그램상의 에러가 발생했을 때 예외가 발생한다.
ex) nextInt() 메소드는 숫자만을 입력 받는 기능을 하는데 여기에 문자를 입력한다면 예외(에러)가 발생

예외가 발생할 때 적절한 처리를 해주지 않으면 프로그램이 종료되어버리기 때문에 예외는 상황별로 다른 예외를 발생시켜야 한다. 예외는 "던져진다"라고 표현한다. 예외 처리는 try ~ catch 라는 키워드를 사용한다.
예외를 우리가 생성할 수도 있다.

예외는 밑에서부터 위로 발생한다.


# 예외 발생


맨 밑줄에서부터 위로 실행을 시켜서 올라가기 때문에 InputMissmatchExceptionTest.java의 27번째 라인에서 발생이 된다고 하면 된다.

InputMismatchException이란 에러는 Scanner 사용시 자주 발생되는 예외이다.
에러 발생 시 첫 줄을 복사 후 구글에 검색하여 어떤 에러인지 찾아도 된다.

# 예외 처리하기
에러가 날 가능성은 13번째 줄 

 라고 볼 수 있다.
여기서 무조건 예외가 발생하는 것은 아니므로 예외가 발생할 수 있는 상황을 잡아준다.
catch ( 에러발생하는 Exception 추가 후 대문자와 따와서 ime 인스턴스 화 시킴)


try는 예외 발생 가능성이 있는 코드를 작성한다. 그래서 에러가 발생 시 catch 부분으로 던져지고
catch가 실행되는 동안 프로그램의 종료는 되지 않고 catch의 문장을 실행 한다.

# 예외 발생 시 무한 반복하기


while문을 통해서 예외 발생 시 반복을 하고 try에서 예외 상황이 없다면 break; 처리하면 된다
하지만 그냥 반복하게 되면 입력을 안받고 무한 반복이 되게 되는데 이런 경우 catch에서 input을 재 초기화를 시켜줘야 해결이 된다

프로그램 결과



# 예외 처리하고 에러 발생 보기
  1. 사용하면 안되는 코드 (보안 문제)


  1. 애용해야 할 코드


프로그램 결과



# 이전 과제 예외 처리 해보기

10개의 배열에 입력 받는 메소드


10개의 배열에 정수를 입력 받는 메소드이다. 기존의 프로그램은 전체적으로 10번을 입력 받는 while에 범위 값을 지나가면 if문을 통해서 걸러 내고 while 1 반복되지만 input 받을 때의 문자열을 입력 받았다면 예외 발생으로 프로그램이 종료되었다. 
그래서 this.score에 입력 받는 경우 try (에러 발생 가능성 코드)를 설정하고 catch ( InputMismatchException ime ) 을 통해 발생시에 Scanner를 재 초기화 시켜주고 예외 발생을 알린 후 i 번째 배열의 정수 값을 재 입력 받는다


# 주로 발생하는 예외
주로 발생하는 예외들은 다음과 같다
  • InputMismatchException
  • Arithmeticexception
  • NullPointerException
  • ArrayOutofBoundsException
  • NumberFormatException
  • FileNotFoundException
  • ClassNotFoundException- 발생 시킬 수 없지만 나중에 종종 발견됨
  • 사용자가 예외를 만들어서 던질 수도 있다


1. ArtithmeticException
정수를 0으로 나눌 때 발생하는 예외


try catch로 ArithmeticException을 잡는 과정이다.
프로그램에서 arithmetic 에러를 던지지 않아 에러 내용은 확인을 할 수 가 없었다.


2. NumberFormatException
문자를 정수나 실수, 논리형으로 변환 시 발생할 수 있는 예외
정수형으로 변경할 때 실수형 숫자의 문자 값 입력 시 발생

문자를 다른 타입으로 변환하는 래턴
문자를 다른 타입으로 변환할 때 Wrapper Class 사용한다



Wrapper.parse타입 ( 문자열 변수 )를 넣으면 변환을 할 수 있다
웹에서 사용자에게 입력받는 모든 것을 타입 변경할 때 자주 사용 된다.

예외 처리


예외 처리 결과


문자를 숫자로 바꾸는 메소드 (자주 사용됨)

문자 -> short, double, float 모두 가능

  • InputMismatchException - 발생할 가능성 적음
  • Arithmeticexception - 발생할 가능성 적음
  • NullPointerException - 발생 빈도 높음
  • ArrayOutofBoundsException
  • NumberFormatException
  • FileNotFoundException
  • ClassNotFoundException - 발생 시킬 수 없지만 나중에 종종 발견됨


3. ArrayIndexOutOfBoundsException

배열의 없는 인덱스에 값을 넣을 때 발생된다
try ~ catch 하지 않고 에러날 코드를 제거한다
개발자의 실수가 아니라면 발생하지 않는다.

프로그램


프로그램 결과



4. FileNotBoundException
파일을 찾을 수 없을 때 발생하는 예외

프로그램

에러가 발생할 가능성이 높으니 잡고 시작하라고 알려주는 형태이다.
Surround with try/catch를 선택한다면 
다음과 같이 바꿀 수 있다



프로그램 결과


파일을 찾아서 읽는데 파일이 없을 때 발생하는 경우이다. 


5. NullPointerException

기본형 타입의 기본 값은 위의 값들과 같지만 참조형 변수의 기본 값은 모두 null 값이다

프로그램


프로그램 결과


null 값은 비어 있는 값이다 String은 생성자로 선언되어 있지 않기 때문에 equals 메소드를 사용할 수 없는 것이다 인스턴스화 시키지 않았기 때문에
실체화가 되지 않은 인스턴스를 (null로 선언된) NullPointer라고 한다 잘못된 null 참조

절대 try ~ catch 하면 안된다
해결하는 것에 2가지 방법이 있다
  1. String str = null이 아닌 new 키워드로 선언 (실체화를 시켜줌) 사용하지 않음

    실체화 했기 때문에 NullPointer 예외 발생 하지 않는다 메모리가 효율적이지 못하다 null은 null로 놔두는 게 좋다

  1. 논리 연산을 사용한다 if 문 자체에 str!= null && 을 통해서 null 값을 제외 시켜 버린다
    

     null 값인 str이 들어오면 && 연산에서 false 이므로 뒤의 조건이 어떻게 나와도 false가 나온다

예외 처리의 finally

# finally
예외 처리 구문에서 예외 처리 행동을 한 이후 무조건 실행되는 문장


예외가 발생하나 발생하지 않으나 finally의 숫자 변환 종료는 무조건 출력이 된다


# 예외 처리 내의 예외 처리
  1. catch()를 문장 추가하여 예외 처리를 할 수 있다 1.6ver (예외 처리 개별 처리)

예외 처리를 개별적으로 해줄 때 사용된다

  1. 기존의 catch 문장에 추가하는 방식 1.7ver 이후 (예외 처리 공통 처리)

파이프 추가를 통해서 catch를 할 수 있지만 어떠한 에러인지 모르는 상태이므로 if 문을 통해서 분기를 시켜주면 된다


throws & throw
소스에서 에러 발생 시 JVM으로 에러가 진행되고 JVM이 프로그램을 Kill시켜 프로그램이 종료된다
그것을 처리하는 방법이 try ~ catch로 잡았던 것이다.
try ~ catch는 누가 잡을 것이고 누가 처리할 것인가를 명시한다.

에러에 대한 책임을 전가하는 것이 throws이다

# throws
throws는 메소드 즉 선언된 코드에서 예외 처리를 하지 않고 사용자인 호출자 (메소드 호출자)에게 책임을 넘기는 것이다. 그러니 메소드 자체에서 예외 책임을 지지 않으니 try~catch 하지 않고 호출자가 관리를 한다

또한 메소드 즉 선언된 코드에서도 예외 처리를 하고 싶을 땐 자체적으로 try~catch를 진행하고 catch 부분에 호출자에게 throw를 해준다 그러므로 호출자도 예외 처리를 해야 한다 

Main


MakeException Class


try ~ catch하면 되는데 throws를 통해서 하는 이유
자바의 프로그래밍에서 보다는 웹 어플리케이션에서 많이 사용 된다


# throws & throw 개념 차이

Main Code (throws)
예외 처리를 전혀 하지 않고 호출자에게 넘김으로써 책임을 지지 않음

Method Code (throws)


Main Code (throw)


Method Code (throw)
메소드가 예외 처리를 진행 하고 발생한 예외를 호출자에게 넘겨서 다른 작업을 진행함


프로그램 결과

같은 상황의 호출 실패여도 프로그램 결과가 다른 것을 볼 수 있다 
숫자로 바꿀 수 없다는 문구는 메소드 자체 예외 처리한 문장


RuntimeException
처리할 필요가 없는 Exception = try~catch 하지 않아도 된다
처리의 의무를 가지지 않는다


RuntimeException과 Exception을 비교하고 차이점을 알아본다
사용은 RuntimeException 한다

# 사용자 정의 예외
예외를 만들기 위해서는 클래스에 extends (상속) 시킨다


예외 만드는 양식 (외우기)



1 Exception (사용X) - throws와 try~catch가 필요 (의무적)


사용자 정의는 throw를 꼭 해줘야 하는데 throws 작성이 필수이다
throw 되어 호출자에게 보내진다면 호출자는 try~catch를 반드시 해야 한다


예외를 보내기 때문에 무조건 예외에 대해 처리해야 할 의무가 있다




2 RuntimeException - throw와 try~catch 필요 없다 (예외 처리 의무가 아님)


Runtime으로 상속을 하면 throws 적을 필요가 없다
또한 호출자에서 try~catch를 처리할 의무가 없다


웹에서는 예외 처리를 하지 않는다 예외 처리하지 않아도 서버가 죽지 않기 때문에
오히려 사용자에게 예외 발생 경우를 알리는 도구가 될 수 있다

RuntimeException / Exception 차이 개념
RuntimeException은 throw를 안해줘도 되고 예외 처리 또한 우리가 정할 수 있다
예외가 발생하는 구문이라도 예외 처리 안해도 된다
Exception은 throw를 반드시 해줘야 하고 try~catch 또한 반드시 해줘야 한다