- 컴파일 에러 : 컴파일할 때 발생하는 에러
- 런타임 에러 : 실행할 때 발생하는 에러
- 논리적 에러 : 의도와 다르게 동작(실행시)
▶ JAVA의 런타임 에러 - 에러와 예외
- 에러는 어쩔 수 없지만, 예외는 처리해야 한다
- 에러처리의 정의와 목적
- 예외를 처리하려면 try-catch문을 사용해야 한다.
▶ 흐름
예외 클래스는 크게 두 그룹으로 나뉜다.
RuntimeException클래스들
: 프로그래머의 실수로 발생하는 예외 -> 예외처리 선택
Exception클래스들
: 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외 -> 예외처리 필수
- try블럭에서 예외가 발생하면, 발생한 예외를 처리할 catch블럭을 찾음
- 첫번째 catch블럭부터 순서대로 찾아 내려가며, 일치하는 catch블럭이 없으면 예외는 처리되지 않음
- 예외의 최고조상인 Exception을 처리하는 catch블럭은 모든 종류의 예외를 처리할 수 있음( 반드시 마지막 catch블럭이어야 함)
- 발생한 예외 객체를 catch블럭의 참조변수로 접근할 수 있음.
- 예외의 발생여부와 관계없이 실행되어야 하는 코드를 넣음
- 선택적으로 사용할 수 있으며, try-catch-finally의 순으로 구성됨
- 예외 발생시, try → catch → finally의 순으로 실행되고 예외 미발생시 try → finally의 순서로 실행됨
- try 또는 catch블럭에서 return문을 만나도 finally블럭은 수행됨
- 예외를 처리하는 또 다른 방법
- 사실은 예외를 처리하는 것이 아니라, 호출한 메서드로 전달해주는 것
- 호출한 메서드에서 예외처리를 해야만 할 때 사용
- 예외를 처리한 후에 다시 예외를 생성해서 호출한 메서드로 전달하는 것
- 예외가 발생한 메서드와 호출한 메서드, 양쪽에서 예외를 처리해야 하는 경우에 사용
- 기존의 예외 클래스를 상속받아서 새로운 예외 클래스를 정의할 수 있음
- 에러코드를 저장할 수 있게 ERR_CODE와 getErrCode()를 멤버로 추가
주석으로 설명..
package ch08;
// 예외처리
public class S01 {
public static void main(String[] args) {
System.out.println("이전코드");
// try 예외가 일어날 것 같은 코드를 담는 공간
try {
// 예외가 일어날 수 있는 코드
System.out.println(10 / 0);
// catch 특정 예외가 발생했을 때
// 프로그램을 멈추지 않고 처리한 뒤 다음으로 넘긴다
} catch (ArithmeticException e) {
System.out.println("계산 중 예외가 발생했습니다.");
}
System.out.println("다음코드");
}
}
주석으로 설명..
package ch08;
public class S02 {
public static void main(String[] args) {
int[] intArray = {10, 20};
// try {
// // 여기서 에러 발생
// System.out.println(10 / 0);
// // 밑으로 안내려감
// // catch로 바로감
// System.out.println(intArray[2]);
// } catch (ArithmeticException e) {
// System.out.println("계산중 예외가 발생했습니다.");
// }
// try {
// // intArray에서 바로 밑에 catch로 넘어감
// System.out.println(intArray[2]);
// System.out.println(10 / 0);
// // 발생할 수 있는 모든 에러에 대한 처리를 각각 해주는 것이 좋다.
// } catch (ArithmeticException e) {
// System.out.println("계산중 예외가 발생했습니다.");
// } catch (ArrayIndexOutOfBoundsException e1){
// System.out.println("배열검색 범위를 넘어섰습니다.");
// }
try {
System.out.println(10 / 0);
System.out.println(intArray[2]);
// 중요한 코드가 아닐 경우에는
// 한꺼번에 처리할 수도 있다
// 최상위 예외 클래스 Exception
} catch (ArithmeticException e) {
System.out.println("예외가 발생했습니다.");
}
}
}
주석으로 설명..
package ch08;
import java.util.InputMismatchException;
import java.util.Scanner;
public class S03 {
public static void main(String[] args) {
// 스캐너 -> 마지막에 꼭 close()를 해줘야함
Scanner scanner = new Scanner(System.in);
int num;
try {
num = scanner.nextInt(); } catch (InputMismatchException e) {
num = 0;
System.out.println("정수가 아닙니다.");
// finally는 try안의 변수와 관련된 객체가
// 무조건 처리되어야 할 경우 사용한다.
// try안의 코드가 예외가 발생하든 안하든 무조건 실행된다.
} finally {
scanner.close();
}
System.out.println(num);
}
}
주석으로 설명..
package ch08;
import java.util.InputMismatchException;
import java.util.Scanner;
public class S04 {
public static void main(String[] args) {
int num;
// try의 소괄호 안에는
// 자동으로 close 할 수 있는 객체가 들어갈 수 있다.
// finally로 close한 것과 같이 처리된다
try(Scanner scanner = new Scanner(System.in);) {
num = scanner.nextInt();
} catch (InputMismatchException e) { num = 0;
System.out.println("정수가 아닙니다.");
// finally는 try안의 변수와 관련된 객체가
// 무조건 처리되어야 할 경우 사용한다.
// try안의 코드가 예외가 발생하든 안하든 무조건 실행된다.
}
System.out.println(num);
}
}
주석으로 설명..
// 직접 예외를 만들 수 있다
// Exception 또는 RunTimeException을 상속하는 것이 일반적이다
// 아래랑 같음
class NotOneException extends Exception{
public NotOneException(String message) {
super(message);
}
}
class CalcUtil{
// 들어온 정수가 1이면 정상 / 아니면 에러
// throws는 이 함수를 호출한 곳에 에러를 던지겠다라는 뜻
static void checkOne(int num) throws NotOneException{
if (num == 1) {
System.out.println("정상입니다.");
} else {
throw new NotOneException("에러입니다.");
}
}
}
public class S05 {
public static void main(String[] args) {
try {
CalcUtil.checkOne(0);
} catch (NotOneException e) {
System.out.println(e.getMessage());
}
}
}