- 프로그램의 오류 상황 두 가지
컴파일 오류(compile error): 프로그램 코드 자겅 중 실수로 발생하는 오류
실행 오류(runtime error): 실행 중인 프로그램이 의도하지 않은 동작을 하거나 프로그램이 중지되는 오류(=버그)
- 실행 오류 두 가지
자바 가상 머신에서 발생하는 시스템 오류(error)
ex) 사용 가능한 동적 메모리가 없거나 스택 메모리의 오버플로가 발생한 경우
시스템오류는 프로그램에서 제어할 수 없다.
예외(exception)
ex) 프로그램에서 파일을 읽어 사용하려는데 파일이 없는 경우, 네트워크로 데이터를 전송하려는데 연결이 안된 경우, 배열 값을 출력하려는데 배열 요소가 없는 경우
예외는 프로그램에서 제어할 수 있다.
- 예외 처리하기 try- catch문
try{
예외가 발생할 수 있는 코드 부분
}catch(처리할 예외 타입 e){
try 블록 안에서 예외가 발생했을 때 예외를 처리하는 부분
}
package first_project;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ExceptionHandling1 {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("a.txt");
} catch (FileNotFoundException e) {
System.out.println(e);
}
System.out.println("여기도 수행됨");
}
}
결과
java.io.FileNotFoundException: a.txt (지정된 파일을 찾을 수 없습니다)
여기도 수행됨
결과를 보면 예외 처리 후에도 프로그램이 계속 수행되었음을 알 수 있다.
- try-catch-finally문
try{
예외가 발생할 수 있는 부분
}catch(처리할 예외 타입 e){
예외를 처리하는 부분
}finally{
항상 수행되는 부분
}
리소스를 열기만 하면 문제가 발생하기 때문에 사용 자원을 close()로 닫아주어야 한다. 다음과 같이 작성할 수 있다.
package first_project;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionHandling1 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("a.txt");
} catch (FileNotFoundException e) {
System.out.println(e);
}finally {
if(fis != null) {
try {
fis.close(); // 파일 입력 스트림 닫기
}catch(IOException e){
e.printStackTrace();
}
}
System.out.println("finally 항상 수행됨");
}
System.out.println("여기도 수행됨");
}
}
결과
java.io.FileNotFoundException: a.txt (지정된 파일을 찾을 수 없습니다)
finally 항상 수행됨
여기도 수행됨
- throws로 예외 처리 미루기
예외를 해당 메서드에서 처리하지 않고 미룬 후, 메서드를 호출하여 사용하는 부분에서 예외를 처리하는 방법
loadClass메서드는 throws를 이용해 예외처리를 미루었으므로 이 메서드를 호출하는 부분에서 예외 처리가 이루어져야 한다. 그런데 16째 줄을 보면 호출부에서 예외 처리 코드가 작성되지 않았기 때문에 빨간 줄이 그어진다. 아래와 같이 작성할 수 있다. 빨간 줄에 마우스를 올리면 세 가지 옵션이 나오는데 그 중 세번째 옵션을 택하면 다음과 같아진다.
package first_project;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ThrowsException {
public Class loadClass(String fileName, String className) throws FileNotFoundException, ClassNotFoundException{
FileInputStream fis = new FileInputStream(fileName);
Class c = Class.forName(className);
return c;
}
public static void main(String[] args) {
ThrowsException test = new ThrowsException();
try {
test.loadClass("a.txt", "java.lang.String");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- 사용자 정의 예외
사용자 정의 예외 클래스를 구현할 땐 기존 JDK에서 제공하는 예외 클래스 중 가장 유사한 클래스를 상속받는 것이 좋으나, 잘 모르겠다면 가장 상위클래스인 Exception 클래스를 상속받으면 된다.
package first_project;
public class IDFormatException extends Exception {
public IDFormatException(String message) {
super(message);
}
}
package first_project;
public class IDFormatTest {
private String userID;
public String getUserID() {
return userID;
}
public void setUserID(String userID) throws IDFormatException{ //예외를 메서드가 호출될 때 처리하도록 미룸
if(userID == null) {
throw new IDFormatException("아이디는 null일 수 없습니다."); //강제로 예외를 발생시킴.
}
else if(userID.length() < 8 || userID.length()>20) {
throw new IDFormatException("아이디는 8자 이상 20자 이하로 쓰세요."); //강제로 예외를 발생시킴.
}
this.userID = userID;
}
public static void main(String[] args) {
IDFormatTest test = new IDFormatTest();
String userID = null;
try {
test.setUserID(userID);
} catch (IDFormatException e) {
System.out.println(e.getMessage());
}
userID = "1234567";
try {
test.setUserID(userID);
} catch (IDFormatException e) {
System.out.println(e.getMessage());
}
}
}
결과
아이디는 null일 수 없습니다.
아이디는 8자 이상 20자 이하로 쓰세요.
댓글