

Throwable 클래스?
오류나 예외에 대한 메시지를 담는 것(getMessage(), printStackTrace())

자바에서의 모든 예외 오류는 Exception 클래스에서 처리한다.
Exception 및 하위 클래스
RuntimeException 클래스
런타임 예외 클래스 종류
1. ArrayIndexOutOfBoundsException

2. ArithmeticException

3. NullPointException // 자바에서 가장 자주 발생하는 에러

4. NumberFormatException

5. ClassCastException

6. InputMismatchException

1. IOException

2. FileNotFoundException
Checked Exception
반드시 예외 처리
Unchecked Exception
반드시 처리를 안해도 된다.
Checked Exception vs Unchecked Exception --> 반드시 예외 처리를 하냐 마냐?

Checked Exception이 발생 가능한 메소드는 try -catch감싸거나, throws로 던져서 처리해야 한다.
Unchecked Exception -->자바 컴파일러가 별도의 예외 처리를 하지 않도록 설계되어 있기 때문에, 예외 처리를 반드시 하지 않아도 된다.(try-cath문으로 감싸지 않아도 된다.)

// 프로그램 실행 시 발생할 수 있는 예외적인 일들을 대비해 코드를 작성하는 행위
미리 대응 코드를 작성함으로써 프로그램의 비정상적인 동작 or 종료를 막아서 프로그램의 정상적인 실행상태를 유지할 수 있도록 하는 것

//1.printStackTrace() : 가장 첫 줄에는 예외 메시지를 출력하고, 두 번째 줄부터는 예외가 발생하게 된 메서드들의 호출 관계를 출력한다.
//2.getMessage(): 예외 메시지를 String 형태로 저공 받는다. 예외가 출력되었을 때, 어떤 예외가 발생되었는지 확인할 때 상용한다.
//3.toString(): 예외 메시지를 String 형태로 제공받는다. getMessage() 보다 더 자세하게, 예외 클래스 이름을 함께 제공한다.
package javaplus.exception;
public class ExceptionEx1 {
public static void generateException(){
try{
int result = 10 / 0; // 이 코드는 ArithmeticExceptoin을 발생시킨다.
}catch(ArithmeticException e){
System.out.println("ArithmeticException 발견");
System.out.println("printStackTrace(): ");
e.printStackTrace();
//getMessage() 메서드 : 예외 메시지를 반환한다.
System.out.println("\n getMessage(): ");
System.out.println(e.getMessage());
//toString() 메서드 : 예외의 간략한 설명(클래스 이름 + ":" + 메시지)을 반환한다.
System.out.println("\n toString(): ");
System.out.println(e.toString());
}
}
public static void main(String[] args) {
generateException();
}
}
ArithmeticException 발견
printStackTrace():
getMessage():
/ by zero
toString():
java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
at javaplus.exception.ExceptionEx1.generateException(ExceptionEx1.java:7)
at javaplus.exception.ExceptionEx1.main(ExceptionEx1.java:24)
Process finished with exit code 0

IOException의 경우, 컴파일 오류이기 때문에 실행 자체가 되지 않는다. 따라서 위와 같이 try catch문으로 넣어줘야 한다.
try 블록은 예외가 발생할 수 있는 영역을 감싼다.(예외 발생 가능성이 있는 코드)
//try 블록에서 예외가 발생하면 그 뒤의 코드들은 수행하지 않고 catch 블록으로 점프한다.
cath 블록은 발생한 예외를 처리하는 코드를 작성한다.(예외가 발생했다면 ~을 해라)
// 소괄호는 예외의 종류를 적어준다(IOException, NullPointException ,,,,,)

//예외가 발생하는 시점을 우리가 아는 것
//보통 문법적으로 문제가 되는 상황에서는 JVM(자바 가상 머신)이 적절한 예외를 발생시킨다.



위 코드를 예외 처리를 해보면

여기서 throw라는 것은 예외가 발생하는 시점에 예외를 발생시키라는 의미이다.
//사용자가 일부러 에러를 throw해서 에러를 catch하는 개념
throws는 예외가 발생한 메소드에서 예외 처리를 하는 것이 아니라, 메소드를 호출한 곳에서 예외 처리하는 것이다.
//메소드 선언부 끝에 작성
//나를 호출한 곳으로 예외를 던져주는 개념
//가독성을 위함(throw를 해주게 되면, 메소드모다 try-catch문을 써줘야 한다.)
// throw - 예외를 발생시키는 것 / throws - 예외를 메서드에 선언하는 것
//예문
public class Main {
public static void main(String[] args) {
try {
method1();
method2();
method3();
} catch (ClassNotFoundException | ArithmeticException | NullPointerException e) {
System.out.println(e.getMessage());
}
}
public static void method1() throws ClassNotFoundException {
throw new ClassNotFoundException("에러이지롱");
}
public static void method2() throws ArithmeticException {
throw new ArithmeticException("에러이지롱");
}
public static void method3() throws NullPointerException {
throw new NullPointerException("에러이지롱");
}
}

new 생성자로 예외 클래스를 초기화하고, 이 클래스 생성자에 입력값을 주게되면, catch문의 getMessage() 메서드에서 출력할 메세지를 지정하게 된다.



위와 같이 호출한 곳에서 try-catch문을 통해 예외를 처리하게 된다.

첫 try-catch문은 예외가 없기 때문에 정상적으로 출력이 된다.
두 번째 try-catch문은 예외가 존재하므로 OverdraftException이 발생하면서 '잔액이 부족합니다'를 출력한다.
// 한 예외가 다른 예외를 발생시키는 것(다형성을 이용해서 자식 클래스가 부모 클래스를 상속해서 사용하는 것과 비슷한 개념--> 예외의 다형성)
원인 예외(cause exception)
ex) 예외 A가 발생하면 예외 B로 감싸서 throw하는 방식
예외를 다른 예외로 감싸서 던지기
Throwable 클래스에는 getMessage(),printStackTrace() + 연결된 예외를 가능하게 해주는 메서드가 있다.
1. Throwable initCause(Throwable cause) : 해당 예외를 원인 예외로 설정
2. Throwable getCause(): 원인 예외로 반환
//이는 Throwable 클래스에 정의되어 있는 것이기 떄문에 모든 예외 클래스에서 사용 가능하다.
class InstallException extends Exception { ... }
class SpaceException extends Exception { ... }
class MemoryException extends Exception { ... }
public class Main {
public static void main(String[] args) {
try {
install();
} catch (InstallException e) {
System.out.println("원인 예외 : " + e.getCause()); // 원인 예외 출력
e.printStackTrace();
}
}
public static void install() throws InstallException {
try {
throw new SpaceException("설치할 공간이 부족합니다."); // SpaceException 발생
} catch (SpaceException e) {
InstallException ie = new InstallException("설치중 예외발생"); // 예외 생성
ie.initCause(e); // InstallException의 원인 예외를 SpaceException으로 지정
throw ie; // InstallException을 발생시켜 상위 메서드로 throws 된다.
} catch (MemoryException e) {
// ...
}
}
}
사용하는 이유
1.여러가지 예외를 하의 예외로 묶어서 다루기 위함이다.
2.무슨 에러 때문에 이러한 에러가 났는지 확인하기 용이하기 때문에 사용한다.
3. checked 예외를 unchecked 예외로 바꿀 수 있도록 하기 위함
class MyCheckedException extends Exception { ... } // checked excpetion
public class Main {
public static void main(String[] args) {
install();
}
public static void install() {
throw new RuntimeException(new IOException("설치할 공간이 부족합니다."));
// Checked 예외인 IOException을 Unchecked 예외인 RuntimeException으로 감싸 Unchecked 예외로 변신 시킨다
}
}
IOException의 경우 Cehecked exception이기 때문에, 반드시 try-catch문으로 감싸줘야 한다.
이러한 번거로움을 없애기 위해 checked exception을 unchecked exception으로 감싸줘서 예외처리를 선택적으로 하게 바꿔준다.
