본문 바로가기

JAVA

JAVA 예외처리

반응형

컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용 프로그램 실행 오류가 발생하는것을 자바에서 error 라고 한다. 에러는 JVM위에서 실행되는 프로그램을 아무리 견고하게 만들어도 결국 실행 불능이 된다. 개발자는 이런 에러에 대처할 방법이 전혀 없다. 자바에서는 에러 이외에 예외라고 부르는 오류가 있다. 예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다. 예외가 발생되면 프로그램은 곧 바로 종료된다는 점에서 에러와 동일하다. 그러나 예외처리를 통해 프로그램을 종료하지 않고 정상 실행 상태가 유지 되도록 할수 있다.

 

예외는 두가지 종류가 있다. 하나는 일반예외이고 다른하나는 실행예외이다. 일반 예외는 컴파일러 체크 예외라고도 하는데, 자바 소스를 컴파일하는 과정에서 예외 처리 코드가 필요한지 검사하기 때문이다. 만약 예외 처리 코드가 없다면 컴파일 오류가 발생한다. 실행예외는 컴파일하는 과정에서 예외 처리 코드를 검사하지 않는 예외를 말한다. 컴파일 시 예외 처리를 확인하는 차이일뿐, 두 가지 예외는 모두 예외 처리가 필요하다. 자바에서는 예외를 클래스로 관리한다.  JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성한다. 그리고 나서 예외 처리 코드에서 예외 객체를 이용할 수 있도록 해준다. 모든 예외 클래스들은 다음과 같이 java.lang.Exception 클래를 상속받는다.

 

 

 

 

일반 예외와 실행 예외 클래스를 구별하는 방법은 일반 예외는 Exception을 상속받지만 RuntimeException을 상속받지 않는 클래스들이고, 실행 예외는 다음과 같이 RuntimeException을 상속받은 클래스들이다. RuntimeException 역시 Excetpion을 상속받지만 , JVM은 RuntimeException 을 상속했는지 여부를 보고 실행 예외를 판단한다.

 

 

 

실행예외

 

실행예외는 자바 컴파일러가 체크를 하지 않기 때문에 오로지 개발자의 경험에 의해서 예외 처리코드를 삽입해야한다. 만약 개발자가 실행예외에 대해 예외 처리 코드를 넣지 않았을 경우 해당예외가 발생하면 프로그램은 곧바로 종료된다. 

 

 

NullPointerException

 

 

 

 

자바 프로그램에서 가장 빈번하게 발생하는 실행 예외는 java.lang.NullPointerException 일 것이다. 이것은 객체 참조가 없는 상태, 즉 null 값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생한다. 객체가 없는 상태에서 객체를 사용하려 했으니 예외가 발생하는것이다. 

 

data변수는 null값을 가지고 있기 때문에 String 객체를 참조하고 있지 않다. 하지만 String 객체의 toString() 메소드를 호출하고 있다. 여기서 NullPointerException이 발생한다.

 

 

 

ArrayIndexOutOfBoundsException

 

 

배열에서 인덱스 범위를 초과하여 사용할 경우 실행 예외인 java.lang.ArrayIndexOutOf-BoundsException이 발생한다. 예를 들어 길이가 3인 int [] arr = new int[3] 배열을 선언했다면 배열 항복을 지정하기 위해 arr[0] ~ arr [2] 를 사용할수 있다. 하지만 arr[3]을 사용하면 인덱스 범위를 초과 했기 때문에 ArrayIndexOutOfBoundsException이 발생한다.

 

위 그림에서 ArrayIndexOutOfBoundsException이 발생한다. 그 이유는 두개의 실행 매개값을 주지 않았기 때문이다. 대문에 args[0] , args[1] 와 같이 인덱스를 사용할 수 없다.

 

NumberFormatException

프로그램을 개발하다 보면 문자열로 되어 있는 데이터를 숫자로 변경하는 경우가 자주 발생한다. 문자열을 숫자로 변환하는 방법은 여러 가지가 있지만 가장 많이 사용되는 코드는 다음과 같다.

 

반환타입 메소드명(매개변수) 설명
int Integer.parseInt(Stirng s) 주어진 문자열을 정수로 변환해서 리턴
double Double.parsedDouble(String s) 주어진 문자열을 실수로 변환해서 리턴

 

 

 

 

Integer와 Double은 포장(Wrapper) 클래스라고 한다

메소드를 이용하면 문자열을 숫자로 변환할 수 있다. 이메소드들은 매개값인 문자열이 숫자로 변환될수 있다면 숫자를 리턴하지만, 숫자로 변환될 수 없는 문자가 포함되어 있다면 java.lang.NumberFormatException 을 발생시킨다.

 

위에 코드를 보면 "100" 문자열은 숫자로 변환이 가능하기 때문에 정상적으로 실행이 되지만 data2변수의 "a100"  문자열은 숫자로 변환할 수  없기 때문에 다음과 같이 NumberFormatException이 발생한다.

 

 

 

 

ClassCastException

타입변환은 상위 클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에도 발생한다. 이러한 관계가 아니라면 클래스는 다른 클래스로 타입 변환될수 있다. 억지로 타입 변환을 시도할 경우 ClassCastException이 발생한다. 

 

 

다음은 올바른 타입 변환을 보여준다. Animal 타입 변수에 대입된 객체가 dog이므로 dog타입으로 변환 하는것은 아무런 문제가 없다.

마찬가지로 RemoteControl타입 변수에 대입된 객체가 Television이므로 Television타입으로 변환하는것은 아무런 문제가 없다.

 

 

하지만 대입된 객체가 아닌 다른 클래스 타입으로 타입변환을 하게 되면 ClassCastException이 발생한다.

 

ClassCastException을 발생시키지 않으려면 타입 변환 전에 타입 변환이 가능한지 instanceOf연산자로 확인하는 것이 좋다.

instanceOf 연산자의 결과가 true 이면 좌항 객체를 우항 타입으로 변환이 가능하다는 뜻이다.

 

 

 

 

예외 처리 코드

 

프로그램에서 예외가 발생했을 경우 프로그램의 갑작 스러운 종료를 막고, 정상실행을 유지할수 있도록 처리하는 코드를 예외처리 코드라고한다. 자바 컴파일러는 소스 파일을 컴파일할 때 일반 예외가 발생할 가능성이 있는 코드를 발견하면 컴파일 오류를 발생시켜 개발자로 하여금 강제적으로 예외처리 코드를 작성하도록 요구한다. 그러나 실행예외는 컴파일러가 체크해주지 않기 때문에 예외처리 코드를 개발자의 경험을 바탕으로 작성해야한다..ㅠㅠ 예외 처리코드는 try-catch-finally블록을 이용한다. 블록은 생성자 내부와 메소드 내부에서 작성되어 일반 예외와 실행 예외가 발생할 경우 예외처리를 할수 있도록 해준다.

 

try블록에는 예외 발생 가능 코드가 위치한다. try 블록의 코드가 예외 발생 없이 정상 실행되면 catch 블록의 코드는 실행되지 않고 finally 블로그이 코드를 실행한다. 만약 try 블룩의 코드에서 예외게 발생하면 즉시 실행을 멈추가 catch 블록으로 이동하여 예외처리 코드를 실행한다. 그리고 finalliy블록의 코드를 실행한다.  catch 블록으로 이동하여 예외 처리 코드를 실행한다.  try블로과 catch블록에서 return문을 사용하더라도 finally블록은 항상 실행된다.

 

 

 

 

ClassforName()메소드는 매개값으로 주어진 클래스가 존재하면 Class 객체를 리턴하지만 존재하지 않으면 ClassNotFoundException 예외를 발생시킨다. ClassNotFoundException 예외는 일반 예외이므로 컴파일러는 개발자로 하여금 예외 처리 코드를 위에 코드처럼 작성하도록 요구하게 된다 위에 코드는 java.lang.String2 라는 클래스는 존재하지 않는다 예외가 발생하면 System.out.println 이 실행되어 예외처리를 하게된다.

 

 ArrayIndexOfBoundException이나, NumberFormatException 과 같은 실행 예외는 컴파일러가 예외 처리 코드를 체크하지 않기 때문에 오로지 개발자의 경험에 의해 예외 처리를 작성해야한다.

 

반응형

'JAVA' 카테고리의 다른 글

사용자 정의 예외와 예외 발생  (0) 2020.11.16
예외 종류에 따른 처리코드  (0) 2020.11.16
클래스의 구성 멤버(return)  (0) 2020.11.11
클래스의 구성 멤버(메소드)  (0) 2020.11.11
클래스의 구성 멤버(생성자)  (0) 2020.11.11