🔷 어떤 원인에 의해 오동작 하거나 비정상적으로 종료되는 경우
컴파일 에러(compile-time error)
: 문법적 오류런타임 에러(runtime error)
: 실행 과정에서 발생하는 에러논리적 에러(logical error)
: 의도와 다르게 나오는 것에러(error)
스택 오버 플로우(Stack over flow)
: 스택 메모리 공간에서 데이터를 감당하지 못하고 넘칠 때 발생💡 스택 오버 플로우는 재귀호출 시에 자주 발생하는 에러이다.
예외(Exception)
🔷 예외 발생 시 프로그램의 비 정상 종료를 막고 정상적인 실행 상태를 유지하는 것
🔷 예외의 계열
RuntimeException
클래스들unchecked exception
❗ 프로그래머가 직접 체크해야한다.
Exception
클래스들checked exception
int [] nums = {10};
// UnChecked Exception
System.out.println(nums[2]);
// Checked Exception
Thread.sleep(1000);
🔷 예외 처리 키워드
try
catch
finally
throws
throw
🔷 예외처리 (try~catch 구문)
JVM
의 예외처리기가 받아서 처리try-catch
구문이 올 수 있음.try {
// 예외가 발생할 수 있는 코드
// 정상 코드
} catch (Exception e) {
// 예외가 발생했을 때 처리할 코드
}
// 일반 코드
// 1. 예외가 발생했을 때: 1-3-4
int [] nums = {10};
try {
System.out.println(nums[2]); // 예외가 발생할 수 있는 코드
System.out.println();
int n = 10; // 정상 코드
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("크기를 벗어나 버림;"); // 예외 발생 시 처리 코드
}
System.out.println("종료"); // 일반 코드
// 2. 예외가 발생하지 않았을 때: 1-2-4
try {
System.out.println(nums[0]); // 예외가 발생할 수 있는 코드
System.out.println();
int n = 10; // 정상 코드
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("크기를 벗어나 버림;"); // 예외 발생 시 처리 코드
}
System.out.println("종료"); // 일반 코드
// 3. 예외를 처리하지 못했을 때: 1-중단
try {
System.out.println(nums[2]); // 예외가 발생할 수 있는 코드
System.out.println();
int n = 10; // 정상 코드
} catch (InputMismatchException e) {
System.out.println("크기를 벗어나 버림;"); // 예외 발생 시 처리 코드
}
System.out.println("종료"); // 일반 코드
🔷 다중 예외처리
try {
// 예외가 발생할 수 있는 코드
} catch (XXException e) {
// XX 예외가 발생했을 때 처리할 코드
} catch (YYException e) {
// YY 예외가 발생했을 때 처리할 코드
}
try {
// 예외가 발생할 수 있는 코드
} catch (XXException e | YYException e) {
// 필요시 instanceof를 통해 나누어 작성
if(e instanceof XXException)
// XX 예외가 발생했을 때 처리할 코드
else
// YY 예외가 발생했을 때 처리할 코드
}
❗ 다중 예외처리 유의 사항
catch
문장을 찾을 때는 다형성
이 적용됨catch
블록은 동작할 기회가 없음🔷 Exception
인스턴스의 주요 메서드
getMessage()
: 발생된 예외에 대한 구체적인 메시지를 반환printStackTrace()
: 예외 발생 당시의 호출 스택(Call Stack)을 출력한다.🔷 메서드에서 예외 던지기
throws
키워드를 사용하여 예외 작성,
를 이용하여 나열public class ThrowsTest01 {
public static void main(String[] args) throws ClassNotFoundException {
// 내부에서 객체를 생성하거나 static 메서드로 변경
method1();
}
public static void method1() throws ClassNotFoundException {
method2(); // 메인 메서드로 처리 위임
}
public static void method2() throws ClassNotFoundException {
// Checked exception
Class.forName("GUE"); // 1번 메서드로 처리 위임
}
}
public class ThrowsTest02 {
public static void main(String[] args) {
try {
method1();
} catch (ArithmeticException e) {
System.out.println("그건 안돼용");
}
}
public static void method1() {
method2(); // 메인 메서드로 처리 위임
}
public static void method2() {
// Unchecked exception
int i = 1/0; // 1번 메서드로 처리 위임
}
}
🔷 메서드 재정의와 throws
import java.io.FileNotFoundException;
import java.io.IOException;
class Parent {
public void methodA() throws IOException {
}
public void methodB() throws ClassNotFoundException {
}
}
public class ThrowsTest02 extends Parent {
public static void main(String[] args) {
}
@Override
public void methodA() throws FileNotFoundException {
}
// 부모가 던지는 예외보다 더 큰 예외를 자식이 던질 수 없음.
@Override
public void methodB() throws Exception {
}
}
🔷 finally
구문
finally
는 예외 발생 여부와 상관 없이 언제나 실행try {
// 1. 예외가 발생할 수 있는 코드
return;
} catch (XXException e) {
// 2. XX 예외가 발생했을 때 처리할 코드
} catch (YYException e) {
// 3. YY 예외가 발생했을 때 처리할 코드
} finally {
// 4. 예외 상관 없이 무조건 실행
}
try - catch - finally
순으로 코드 실행try - finally
순으로 코드 실행return
이 있어도 finally
블록 수행 후 반환1 - 4 - return
🔷 자동 자원 반납 구문 (try with resources)
finally
에서 close()
를 통해 반납을 주로 함.// 기존의 지저분한 코드
try {
fis = new FileInputStream("test.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if(fis != null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try()
-> 괄호 안에 객체를 생성하는 코드를 작성하면, 해당 객체는 close()
를 호출하지 않아도 블록을 벗어나는 순간 close()
가 호출됨.AutoCloseable
이라는 인터페이스를 구현한 클래스이어야만 함.// try with resources
try(FileInputStream fis2 = new FileInputStream("test.txt")) {
} catch (Exception e) {
e.printStackTrace();
}
🔷 사용자 정의 예외
Exception
또는 RuntimeException
클래스를 상속받아 작성checked exception
활용: 명시적 예외 처리 또는 throws
필요💡 코드는 복잡해지지만 처리, 누락 등 오류 발생 가능성은 down
runtime exception
활용: 묵시적 예외 처리 가능💡 코드는 간결해지지만 처리, 누락 등 발생 가능
public class MadeException extends Exception {
// 코드
}
public class ThrowsTest {
public static void main(String[] args) throws MadeException{
throw new MadeException();
}
}