- 예외 (Exception) : 프로그램이 실행되는 과정에서 만나게 되는 오류
* 예외의 종류
- Checked Exception (컴파일 에러)
ㄴ 컴파일러가 판단 할 수 있는 예외. 즉, 실행되기전에 체크 할 수 있는 예외
ㄴ 컴파일 하기 위해서는 반드시 예외 처리 해야한다 (Syntax오류, IOException 등)
ㄴ main에서 던져도 됨. 직접 try~catch로 처리 안해도 된다
ㄴ 외부자원을 쓰려면 빨간줄이 간다
- Unchecked Exception(런타임 에러) - 예외처리한다
ㄴ 컴파일러가 판단 할 수 없는 예외.즉 실행시에만 발견되는 에러
ㄴ JVM이 자동으로 예외를 throws 해 줌으로 예외처리를 하지 않도 된다
ㄴ RuntimeException게열
(NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException 등)
ㄴ 반드시 try~catch해야함
- Error : 치명적 에러로 발생 되더라도 적절한 처리를 할 수 없음
- Error도 역시 Unchecked Exception에 속함 (VirtualMachineError : 자바가상머신에러)
* 예외 처리 목적
- 프로그램 실행시 발생할 수 있는 상황들을 미리 정해놓고, 해당하는 예외가 발생했을 경우 적절한 조치를 취해서
프로그램이 정상적으로 작동하도록 하기 위함이다
예외 처리를 한다는 것은 런타임 에러를 잡는다는 것이다
* 예외 처리 방법
- [방법 1]try ~ catch 문을 이용한 직접 처리 : 구체적인 예외 처리 가능
try {
// 예외 발생할 만한 코드
} catch (해당예외클래스 e) {
// 예외 처리 코드
}
- 하나의 메소드에 두개 이상의 Exception이 발생 할 경우 catch절을 여러개 사용할 수 있다
이때 catch절로 Exception을 잡을 때는 하위 클래스(자식클래스)부터 잡아준다
try {
// 예외 발생할 만한 코드
} catch (예외클래스 e) {
// 예외 처리 코드
} catch (또 다른 예외클래스 e) {
// 또 다른 예외 처리 코드
}
* 숫자 입력 예외 경우
NumberFormatException ArithmeticException .. < Exception
NumberFormatException 와 ArithmeticException는 상속관계가 아님으로 위치에는 상관없으나
Excepion은 모든 예외 클래스의 부모 임으로 항상 다른 예외 클래스 보다 마지막 catch절에서 잡아야 한다
단, 내가 무슨 에러가 발생할지 모르겠다 하면 Exception하나로 잡으면 되지만 각각의 예외를 처리하기 힘들다
- [방법 2]throws 절을 이용한 예외 선언 : 예외 처리를 직접 하지 않고 메소드를 호출하는 쪽으로 넘긴다
public void func() throws IOException {
int number=System.in.read();
}
* func()를 호출하는 쪽으로 IOException 을 넘겨준다.
ex)
public static void exFunc() throws Exception {
out.println("예외를 던지는 메서드");
throw new Exception("예외 받아라");
// 예외를 던지는데 받을 곳을 지정 안 한 경우(throws 생략) 에러,
// throws로 던지던지 자기 자신이 try ~catch로 받던지
// throw한것은 반드시 어느 한곳에서 try~catch 해야 함 계속 던지기만 하면 안됨
// 메인에서 최종적으로라도 try~catch 해야 함
// 단, throw new ~throws 쌍이 아니라 throws한것은 메인에서도 던질 수 있음
// 또한 Checked 예외는 main에서 던질 수 잇으나 런타임 예외는 메인에서 던져도 예외가 발생
}
public static void exCatch() throws Exception {// 여기서도 예외를 처리 안하고 다시 던짐
exFunc();
}
public static void main(String[] args) {
out.println("프로그램 시작");
try {
exCatch();//메인에서 예외 처리
} catch(Exception e) {
out.println(e.getMessage());
}
out.println("프로그램 끝");
}
* finally
- try ~ catch ~ finally / try ~ finally 규칙을 지켜야하며 예외를 잡거나 예외가 발생하지 않더라도 반드시 한번은
수행되는 블럭이다.
- 심지어 return문이 오더라도 finally블럭은 반드시 실행된다 (System.exit(0)의 경우 실행되지 않고 종료된다)
예제)
- try~catch
import java.util.InputMismatchException;
import java.util.Scanner;
public class ExceptionCatchApp {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); // 콘솔에 입력 할수 있는 Scanner클래스
int[] arr = new int[2];
try {
System.out.println("arr[0]방에 입력할 숫자를 입력해 주세요");
arr[0] = Integer.parseInt(sc.nextLine());
System.out.println("arr[1]방에 입력할 숫자를 입력해 주세요");
arr[1] = Integer.parseInt(sc.nextLine());
System.out.println("두 숫자 나누기] = " + arr[0] / arr[1]);
System.out.println("나이를 입력해주세요");
int age = sc.nextInt();
System.out.println("당신의 10년 후 나이는] = " + (age + 10));
} catch (NumberFormatException e) {
System.out.println("숫자만 입력해주세요");
} catch (ArithmeticException e) {
System.out.println("0으로 나눌수 없습니다");
} catch (InputMismatchException e) {
System.out.println("나이는 숫자만 입력해주세요");
} catch (Exception e) {
System.out.println("예외가 발생했습니다");
} // Exception으로 다 잡을수 있으나 각각의 예외를 처리하기 힘듬
}// main
}// class
- try~catch~finally
import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;
public class ExceptionFinallyApp {
// 컴파일 예외 발생 메소드]
static void compile() throws IOException {
System.out.println("한 문자를 입력해주세요");
// 방법1] 예외를 던진다
int ascii = System.in.read();
System.out.println("입력한 문자] = " + (char) ascii);
// 방법2] 직접 try~catch 하면 다른 메소드에서 예외처리 불필요
/*int ascii;
try {
ascii = System.in.read();
System.out.println("입력한 문자] = " + (char) ascii);
} catch (IOException e) {
}*/
}
// 런타임 예외 발생 메소드]
static void runtime() {
Integer.parseInt("백십");
}
static void tryCatchFinally() {
Scanner sc = new Scanner(System.in);
int age = -10;
try {
System.out.println("나이를 입력하세요");
age = sc.nextInt();
// return;// finally절 실행됨
// System.exit(0);
} catch (InputMismatchException e) {
System.out.println("나이는 숫자만 입력해 주세요");
} finally {
System.out.println("당신의 10년 후 나이] = " + (age + 10));
}
}
static void tryFinally() throws IOException {
try {
compile();
} finally {// 반드시 실행할 명령문
System.out.println("반드시 실행할 명령문");
}
}
public static void main(String[] args) throws IOException
/*throws NumberFormatException*/ {
// 방법1] 던지거나
// compile();
// 방법1-1] try~catch
// 방법2]
try {
compile();
} catch (IOException e) {
}
// 런타임 예외는 반드시 try~catch]
try {
runtime();
} catch (Exception e) {
System.out.println("숫자형식이 아닙니다] = " + e.getMessage());
}
tryCatchFinally();
tryFinally();
}// main
}// class
- throws
import java.io.IOException;
public class ExceptionThrowsApp {
// 기존 자바에서 제공해주는 예외를 던지는 메소드(예 - read()) 호출하는 경우]
static void throwsMethodByJava() throws IOException {
System.out.println("문자입력");
System.in.read();
}
static void CallByJava() throws IOException {
throwsMethodByJava();
}
static void throwsMethodByUser(int value) throws Exception{
if (value % 2 == 0) {
// 1] 예외객체 생성
Exception e = new Exception("짝수는 안됩니다");
// 2] 생성된 예외객체 던지기
throw e;
// unreachable code 에러 발생
// System.out.println("throws 이후 출력문");
}
System.out.println(value + "는 홀수");
}
static void callByUser(int value) {
}
public static void main(String[] args) /* 메인에서 던져도 소용없다 throws Exception */
/* throws IOException */ {
// CallByJava();
/*try {// 직접처리
CallByJava();
} catch (IOException e) {
}*/
// callByUser(10); 실행시 역시 오류
try {
callByUser(10);
} catch(Exception e) {
System.out.println(e.getMessage());
}
}// main
}// class
'개발 > JAVA' 카테고리의 다른 글
21. JAVA IO (Input / Output) / 파일 입출력 스트림 / 파일 (File) 클래스 (0) | 2020.06.08 |
---|---|
20. JAVA 쓰레드 (Thread) (0) | 2020.06.08 |
18. JAVA 클래스간 형변환 / 업캐스팅 / 다운캐스팅 / 내부클래스 (InnerClass) (0) | 2020.06.08 |
17. JAVA 인터페이스 (Interface) / 컬렉션 (Collection) (0) | 2020.06.08 |
16. JAVA 배열 (Array) / 헤테로지니어스 (Heterogeneous, 이질화) (0) | 2020.06.08 |