제 7 장 Exception(예외) 처리
■Objective
▶Exception 정의
▶try,catch,finally 구문 사용
▶Common Exception
Exception(예외)
▷ Exception ?
자바에서 exception은 프로그램의 수행 중에 발생할 수 있는 mild error를 말한다.
그러나 exception이 발생했다고 하더라도 무조건 프로그램을 종료하지 않고, error에 적절히 대처하면서 실행을 계속하도록 프로그램을 작성할 수 있다.
▶ 예외란 정상적인 프로그램의 흐름을 방해하는 비정상적인 상황이다.
프로그램이 실행되는 동안 다음과 같은 비 정상적인 상황이 발생할 수 있다.
-열어야 할 파일이 없는 경우
-load할 class 파일이 없거나, 잘못된 포맷인 경우
-네트워크 연결이 끊어진 경우
-피연산자가 연산자나 메소드에서 정의한 범위를 벗어나는 경우,
예를 들면, 배열 요소 인덱스가 배열의 크기를 초과하는 경우 또는 나눗셈에서 0으로 나누는 경우
자바에서는 error에 의해 발생한 exception을 처리하는 방법을 두 가지로 나누어 생각할 수 있다.
- 발생한 곳에서 바로 처리
- Exception을 발생시킨 method를 호출한 caller method에게 처리를 양도(throw)할 수 있다. 이때 caller method는 반드시 자신이 호출하는 method가 throw할 수 있는 exception을 처리할 준비가 되어 있어야 한다.
Exception Categories 자바에서 exception은 크게 세 가지로 나눌 수 있다. java.lang.Throwable class는 throw가 가능하며, catch될 수 있는 모든 object의 부모 역할을 한다.
Throwable class에서는 exception에 대한 정보를 제공하는 다양한 method들을 제공한다.
toString() : Exception에 대한 간단한 설명이 된다.
printStackTrace() : 첫줄은 toString()이 출력되고, 나머지 줄은 exception이 어떤 method들을 거쳐서 catch되었는지를 알려준다.
기타..
Exception을 다음과 같이 세 부류로 나눌 수 있다.
Error : 심각한 error를 말한다. Exception을 받아서 처리할 수 없는 경우를 말한다.
RuntimeException : 컴파일은 되지만 실행시 발생할 수 있는 error를 말한다. 예를 들면 배열의 index에 대한 error와 같은 것을
말한다. RuntimeException은 프로그램의 구조, 즉 설계의 문제라고 할 수 있을 것이다. Object의 null pointer와 관련한 것도
이런 에러를 발생할 수 있다.
Other Exception : 대부분 error에 대한 예상을 할 수 있고, 대처도 가능한 경우를 말한다.
네트웍, 파일등의 IO와 관련된 Exception이 대부분이다.
Common Exceptions
자바에서 기본으로 제공하는 exception 중에서 자주 사용되는 것은 아래와 같다.
》ArithmeticException : 0으로 나누는 경우
예) int i = 12 / 0;
》NullPointerException : 초기화되지 않았거나, null을 가리키고 있는 reference 변수를 사용할 경우
예) Date d = null;
System.out.println( d.toString() );
》NegativeArraySizeException : 배열의 index로 음수를 사용한 경우
》ArrayIndexOutOfBoundsException : 배열의 범위를 넘어서는 index를 사용한 경우
》SecurityException : 보통 brower에서 발생한다. SecurityManager class는 applet이 다음과 같은 동작을 하려고 할 경우에 Exception을 발생시킨다.
- Local file에 access할 경우
- Applet이 download된 host가 아닌곳으로 socket을 열고자 할 경우
- Runtime environment에서 다른 프로그램을 실행하고자 할 경우
Exception Example 1
public class HelloWorld{
public static void main(String args[]){
int i =0;
String greetings[]={
"Hello world",
"No, I mean it!",
"HELLO WORLD!"
};
while(i<4){
System.out.println(greetings[i]);
i++;
}
}
}
| public class HelloWorld{
public static void main(String args[]){
int i=0;
String greetings[]={
"Hello world",
"No, I mean it!",
"HELLO WORLD!"
};
while(i<4){
try{
System.out.println(greetings[i]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Re-setting Index Value");
i=-1;
}catch(Exception e){
System.out.println(e.toString());
}finally{
System.out.println("this is always printed");
}
i++;
}//end while()
}// end main()
|
Runtime시 ArrayIndexOutOfBoundsException가 발생한다.
|
|
Exception Example 2
import java.io.*;
import java.lang.*;
class ExceptionTest{
ExceptionTest(){
StringBuffer Names[] = new StringBuffer[10];
String thisLine = null;
DataInputStream stdIn = new DataInputStream(System.in);
for(int i = 0; i<10 ; i++){
System.out.println(" Input " + i + "'s name");
thisLine = stdIn.readLine();
Names[i]= new StringBuffer(20);
Names[i].append(thisLine);
}
for(int i=0; i<10 ; i++){
System.out.println("Name : " + Names[i]);
}
}
public static void main(String args[]){
ExceptionTest et = new ExceptionTest();
}
}
결과
ExceptionTest.java:13: Exception java.io.IOException must be caught, or it must
be declared in the throws clause of this constructor.
thisLine = stdIn.readLine();
수정
for(int i = 0; i<10 ; i++){
System.out.println(" Input " + i + "'s name");
try{
thisLine = stdIn.readLine();
}catch(IOException e){
System.out.println("Error");
}
Names[i]= new StringBuffer(20);
Names[i].append(thisLine);
}
Exception Handling
1. 직접처리
Exception을 처리하려면 try block을 이용해야한다.
Exception을 발생할 수 있는 code block을 try block으로 처리하고 catch 키워드를 이용하여 원하는 Exception을 처리하면 된다.
이때 처리를 원하는 Exception의 종류를 catch 문에 선언하면 된다.
예외처리의 구조
try{
// cdoe that might throw a particular exception
}catch (MyException Type e){
// code to execute if MyExceptionType is thrown
}finally{
// always execute
}
예)
public class HelloWorld {
public static void main(String []args) {
HelloWorld h= new HelloWorld();
int s[] = {1,2,3}
k=3;
try {
k++;
System.out.println(s[k]);
}
catch(Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}
2. 상위 메소드로 처리 위임(throws)
public class HelloWorld {
public static void main(String []args) {
HelloWorld h= new HelloWorld();
try{
h.go(3);
System.out.println(s[k]);
}
catch(Exception e) {
e.printStackTrace();
System.exit(0);
}
}
public void go(int l)throws Exception
{
int s[] = {1,2,3};
l++;
System.out.println(s[l]);
}
예외처리 우선순위
예외처리시 catch는 여러번 사용이 가능하다. 즉 Exception class 의 하위 class들을 사용하여 그 예외를 처리 해 줄수 있다.
하지만 예외처리시에 자식 class를 먼저 사용하고 나중에 부모를 사용해야 한다. 그렇지 않으면 에러가 발생한다.
예제를 통해서 자세히 살펴 보자.
import java.io.*;
public class TestException4
{
public static void main(String[] args)
{
try{
int c = System.in.read();
}
catch(Exception f)
{
System.out.println(""+f);
}
catch(IOException e)
{
System.out.println(""+e);
}
catch(FileNotFoundException e)
{
System.out.println(""+e);
}
finally
{
System.out.println("끝");
}
}
}
TestException4.java:16: exception java.io.IOException has already been caught
catch(IOException e)
^
TestException4.java:20: exception java.io.FileNotFoundException has already been caught
catch(FileNotFoundException e)
^
2 errors
The Call Stack Mechanism
만약 try/catch block으로 exception을 처리하지 않는다면, exception은 calling method로 전달(throw)되며, 그 calling method도 처리하지 않으면, 또 그 method의 calling method로 전달(throw)된다.
이렇게 아무도 처리하지 않고 결국 main()에서도 처리하지 않으면, 프로그램이 종료되게 된다. 이렇게 method 안에서 exception을 처리하지 않고 throw하기 위해서는 그 method에 throws 키워드로 throw할 exception을 선언해 주어야 한다.
finally Statement
try/catch에 추가적으로 사용되는 finally는 exception의 발생과 무관하게 언제나 수행되는 code block을 말한다.
단 코드의 중간에 System.exit()로 프로그램을 강제로 종료시켰을 경우에는 finally는 실행되지 않는다.
만약 코드의 중간에 return이 있더라도 finally는 실행된다.
Creating Own Exceptions
다음과 같이 Exception을 만들 수 있다.
/*-----------------------------------------------------------------------*/
1) Exception class로부터 상속을 받아서 임의의 Exception class를 만든다.
public class MyException extends Exception { // exception의 정의
public MyException (String message) {
super (message);
}
public MyException() {
this ("My Exception Error");
}
}
2) 임의의 조건에서 Exception을 발생하게 한다.
public void test_ex(int t) throws MyException{ // method 내에 exception 발생을 정의
if (t == -1){
throw new MyException();
}
}
3) Exception이 발생하는 method에서는 그 Exception을 처리한다.
public test_exception(){ // exception 발생을 처리
.....
try{
test_ex(-1);
}catch(MyException e){
System.out.println(e);
}
}