반응형
프로그램에서의 오류
· 컴파일 오류(compile error)
프로그램 코드 작성 중 발생하는 문법적 오류
최근에는 개발 환경(eclipse, intelliJ)에서 대부분의 컴파일 오류는 detection 됨.
· 실행 오류(runtime error)
실행 중인 프로그램이 의도하지 않은 동작(bug)을 하거나 프로그램이 중지되는 오류
실행 오류는 비정상 종료 되는 경우 시스템의 심각한 장애를 발생 가능
예외 처리의 중요성
- 프로그램의 비정상 종료를 피하여 시스템이 원할이 실행되도록 함
- 실행 오류가 발생한 경우 오류의 과정을 재현하는 것은 현식적으로 힘듦
- 오류가 발생한 경우 log를 남겨서 추후 log 분석을 통해 그 원인을 파악하여 bug를 수정
자바는 안정성이 중요한 언어로 대부분 프로그램에서 발생하는 오류에 대해 문법적으로 예외 처리를 해야 함
오류와 예외 클래스
① 시스템 오류 (error) : 가상 머신에서 발생, 프로그래머가 처리할 수 없는 오류
ex. 동적 메모리가 없는 경우, 스택 메모리 오버플로우 등
② 예외(Exception) : 프로그램에서 제어할 수 있는 오류
ex. 읽어 들이려는 파일이 존재하지 않거나, 네트워크이나 DB 연결이 안 되는 경우 등
예외 클래스들
모든 예외 클래스의 최상위 클래스는 Exception 클래스
위에 명시된 클래스보다 더 많은 예외 처리 클래스 존재
예외 처리하기
try-catch 문
- try 블록에는 예외가 발생할 가능성이 있는 코드를 작성
- try 블록 안에서 예외가 발생하는 경우 catch 블록 수행
배열의 오류 처리 예제
배열의 index보다 더 많이 실행했을 경우 오류 발생
public class ArrayIndexException {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
//원래는 i<5 이어야 오류가 없다.
for(int i=0; i<=5; i++) {
System.out.println(arr[i]);
}
System.out.println("here!!");
}
위처럼 코드를 구현했을 때..
length가 5이면 index는 4까지만 호출되어야 하는데 넘어버렸다는 오류 발생
∴ 오류로 인해 코드가 끝가지 실행이 되지 않아서, here!! 메시지는 호출되지 않음
public class ArrayIndexException {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
try {
for(int i=0; i<=5; i++) {
System.out.println(arr[i]);
}
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
System.out.println(e.toString());
}
System.out.println("here!");
}
}
이번엔 try-catch 문을 이용하여 ArrayIndexOutOfBoundsException 예외를 처리해준다.
- 중간에 예외가 발생해도 코드는 끝까지 실행되어 here! 메시지를 호출
- getMessage( ) 메서드를 통해 에러 원인 메서지 호출
- toString( ) 메서드는 Exception의 풀네임과 메세지를 호출
try-catch-finally 문
단순히 try-catch문으로만 Exception을 핸들링할 때
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileExceptionHandling {
public static void main(String[] args) {
FileInputStream fis = null;
//add throws exception -> 내가 처리안하고 던진다는 의미(throws FileNotFoundException)
//Surround with try/catch
try {
fis = new FileInputStream("a.txt");
System.out.println("read");
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace(); //어디서 error가 생겼는지 trace
System.out.println(e);
try {
fis.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
System.out.println("end");
}
}
매우 복잡하다.
try-catch-finally문으로 변환
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileExceptionHandling {
public static void main(String[] args) {
FileInputStream fis = null;
//add throws exception -> 내가 처리안하고 던진다는 의미(throws FileNotFoundException)
//Surround with try/catch
try {
fis = new FileInputStream("a.txt");
System.out.println("read");
} catch (FileNotFoundException e) {
e.printStackTrace(); //어디서 error가 생겼는지 trace
System.out.println(e);
} finally {
if(fis != null) {
try {
fis. close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("finally");
}
//finally는 항상 불린다.
System.out.println("end");
}
}
- try구문이 호출이 됐을 때 finally는 항상 실행이 된다.
더 간단하게는..
try-with-resources문
Java 7부터 가능한 구문
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileExceptionHandling2 {
public static void main(String[] args) {
try(FileInputStream fis = new FileInputStream("a.txt")) {
System.out.println("read");
} catch (FileNotFoundException e) {
// FileNotFoundException은 파일이 없을 때 처리되는 Exception
e.printStackTrace();
} catch (IOException e) {
// close할 때 처리되는 Exception
e.printStackTrace();
}
System.out.println("end");
}
}
- try( ) 내부에서 리소스를 선언
- 리소스를 사용하는 경우 close( )를 명시적으로 하지 않아도 자동으로 해제됨
- 해당 리소스 클래스가 AutoCloseable 인터페이스를 구현해야 함
- 위 코드에서 FileInputStream은 AutoCloseable을 구현하고 있음
- Java 9부터 리소스는 try( ) 외부에서 선언하고 변수만을 try(obj)와 같이 사용 가능
AutoCloseable을 구현
① AutoCloseable을 구현한 클래스
public class AutoCloseableObj implements AutoCloseable {
@override
public void close() throws Exception {
System.out.println("closing...");
}
}
② try-with-resource 방식으로 실행
public class AutoCloseTest {
public static void main(String[] args) {
AutoCloseableObj obj = new AutoCloseableObj();
try(obj) {
} catch(Exception e) {
System.out.println("exception");
}
System.out.println("end");
}
}
- AutoCloseable을 구현한 클래스로 객체를 생성 후
- try( ) 내부에 변수를 넣는다.
- try( ) 구문에는 아무것도 없기 때문에 catch에 걸리지 않고 close( )를 자동으로 진행 후 end
public class AutoCloseTest {
public static void main(String[] args) {
AutoCloseableObj obj = new AutoCloseableObj();
try(obj) {
throw new Exception(); //exception 강제 발생(생성)
} catch(Exception e) {
System.out.println("exception");
}
System.out.println("end");
}
}
throw new Exception( ); 은 exception을 강제 발생
반응형
'개발 > Java' 카테고리의 다른 글
자바의 예외 처리 - 로그 남기기(log) (0) | 2021.05.09 |
---|---|
예외 처리 미루기 (0) | 2021.05.08 |
reduce( ) 연산 (0) | 2021.05.07 |
스트림(Stream) (0) | 2021.05.06 |
람다식(Lambda expression) (0) | 2021.05.05 |