본문 바로가기

코딩공부일지/자바독학

[자바혼공] 예외처리

  • 자료출처

생활코딩 by egoing - 자바: https://opentutorials.org/module/516

남궁석의 자바의정석: https://github.com/castello/javajungsuk_basic/


1. 프로그램 오류

프로그램 실행 중 어떠한 원인에 의하여 프로그램이 오작동하거나 비정상 종료되는 경우, 이러한 결과를 초래하는 원인을 "프로그램 에러" 또는 "오류"라 칭함

발생시점에 따라 "컴파일 에러" / "런타임 에러" / "논리적 에러"로 구분

- 컴파일 에러: 컴파일시에 발생하는 에러
- 런타임 에러: 실행시 발생하는 에러
- 논리적 에러: 실행은 가능하나, 의도와 다르게 동작하는 에러

2. 예외클래스의 계층구조

- 예외(exception):  프로그램 코드에 의해 수습될 수 있는 미약한 오류

- 에러 (error) : 프로그램 코드에 의해 수습불가한 심각한 오류

https://www.geeksforgeeks.org/exceptions-in-java/

* checked exception(Exception 클래스와 그 자손): 예외처리 필수 (try-catch)  / IO excption, ClassNotFoundException, 등
* unchecked exception(RuntimeException과 그 자손): 예외처리 필수아님 / ArithmerticException, ClassCastException 등
 

Exceptions in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

출처: https://www.benchresources.net/exception-hierarchy-in-java/

 

 

Java - Exception Hierarchy - BenchResources.Net

In this article, we will discuss exception hierarchy in detail with figure and explanation Exception Hierarchy: Throwable class is the root class for every exception Read More

www.benchresources.net

Exception클래스와 그 자손: 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
RuntimeException 클래스와 그 자손: 프로그래머의 실수로 발생하는 예외

 

3. 예외 처리하기:

1) try - catch문

예외 처리 (exception handling)
정의: 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것
목적: 프로그램의 비정상 종료를 막고, 정상적인 실행상태 유지

- try-catch 문

try { //예외가 발생할 가능성이 있는 문장들을 기입

} catch ( exception1 e1) { // exception1이 발생했을 경우, 이를 처리하는 문장
} catch ( exception2 e2) { // exception2가 발생했을 경우, 이를 처리하는 문장
} catch ( exception2 e3) { // exception3가 발생했을 경우, 이를 처리하는 문장
} catch ( exception2 e4) { // exception4가 발생했을 경우, 이를 처리하는 문장
}

 => 하나의 try 블럭 다음에는 한 개 이상의 catch 블럭이 올 수 있으며,

 이 중 발생한 예외의 종류와 일치하는 단 한 개의 catch블록만 수행, 발생한 예외 종류와 일치하는 catch블럭이 없을 시 예외는 처리되지 않음

2) try-catch 문의 흐름

* try 블럭 내에서 예외가 발생하는 경우
1. 발생한 예외와 일치하는 catch블럭이 있는지 확인
2. 일치하는 catch블럭이 있을 시, 해당 블럭내 문장 수행 후 전체 try-catch문 벗어남 
   일치하는 catch블럭 없을 시, 예외 처리 불가

*try 블럭 내 예외 미발생시
catch블럭을 거치지 않고 전체 try-catch문 빠져나가 수행 지속
class Ex_1 {
  public static void main(String args[]) {
     System.out.println(1);
     try {
       System.out.println(2);
       System.out.println(3);
     } catch (Exception e) {
        System.out.println(4) ;  // 예외 미발생, 실행되지 않음
     } 
     System.out.prinln(5);
   }
 }
 
 // 결과 1 2 3 5
class Ex8_2 {
  public static void main(String arg[])
    System.out.println(1);
    try {
       System.out.println(0/0); 
       System.out.println(2);   // 실행되지 않음 
    } catch (ArithmeticException ae) {
       System.out.println(3);
    }  //try-catch문의 끝
    System.out.println(4);
   } // main의 끝
}  // class의 끝


// 1 3 4

3) 예외의 발생과 catch 블럭

- catch ( 처리하고자하는 예외와 같은 타입의 참조변수 선언)

- 예외 발생시 발생한 예외에 해당하는 클래스의 인스턴스가 생성---> 예외가 발생한 문장이 try블럭 내 포함되어 있을 시, 해당 예외를 처리할 수 있는 catch 블럭이 있는지 찾게됨

- 모든 예외클래스는 Exception클래스의 자손이므로, catch블럭의 ()에 Exception 타입 참조변수 선언 시 모든 종류의 예외 처리 가능

class Ex8_3 {
  public static void main(String args[]) {
    System.out.println(1);
    System.out.println(2);
    
    try {
      System.out.println(3);
      System.out.println(0/0);  // 예외발생 
      System.out.println(4);  // 미실행 
    } catch (Exception e) {
        System.out.println(5);  //실행 
    }
    // try catch 끝 
    System.out.prinltn(6);
  } // main의 끝
}


// 1 2 3 5 6
class Ex8_4
  public static void main(String args[]) {
    System.out.println(1);
    System.out.println(2);
    try {
      System.out.println(3);
      System.out.println(0/0);
      System.out.println(4);
    } catch (ArithmeticException ae) {
       if ( ae instanceof AtrithmeticException)
         System.out.println("true");
    } catch (Exception e) {
       System.out.println("Exception");
   }  // try-catch의 끝
   System.out.println(6);
  }
}

// 1 2 3 true ArithmeticException 6

4. printStackTrace()와 getMessage()

-예외발생시 생성되는 예외 클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨있으며, getMessage와 printStackTrace를 통해 해당 정보를 얻을 수 있음

-catch블럭의 ()에 선언된 참조변수를  통해 해당 인스턴스에 접근할 수 있음

printStackTrace() 
- 예외발생 당시 호출스텍에 있었던 메서드 정보와 예외 메세지 화면 출력
getMessage()
- 발생한 예외클래스의 인스턴스에 저장된 메세지 출력
class Ex8_5
  public static void main(String args[]);
    System.out.println(1);
    System.out.println(2);
    
    try { 
      System.out.println(3);
      System.out.println(0/0);
      System.out.println(4);
    } catch (ArithmeticException ae) {
        ae.printStackTrace();
        System.out.println(ae.getMessage());
    }  // try-catch의 끝
    System.out.println(6);
  } // main의 끝
}

==> 결과
1
2
3 
java.lang.ArithmeticException: / by zero   // pritnStackTrace();의 결과값
     at Ex8_5.main(Ex8_5.java:8)  
/ by zero                                  // getMessage의 결과값
6

5. 멀티 catch 블럭 ( | )

1번

try { 
} catch ( ExceptionA e) { 
  e.printStackTrace();
} catch ( ExceptionB e2) {
  e.printStackTrace();
}


2번 (멀티캐치 | 사용)


try {
} catch ( ExceptionA | ExceptionB e) {
  e.printStackTrace();
}

- 만약, 멀티캐치블럭 |로 연결된 예외클래스가 조상-자손관계일 시 컴파일 에러발생 (그냥 조상클래스만 써주는 것과 똑같기 때문에 ???????)

6. (고의로) 예외 발생시키기 : throw

1. 연산자 new를 이용하여 발생시키려는 예외 클래스 객체 생성 
    Exception e = new Exception("고의로 발생시켰음")
2. 키워드 throw를 이용해 예외 발생
   throw e;
class Ex8_6
  public static void main(String args[]) {
    try {
      Exception e = new Exception("고의로 발생시켰음")
      throw e;
      
     } catch (Exception e) { 
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
    System.out.println("프로그램이 정상 종료되었음")
   }
 }
 
 
 ===> 결과
 에러메세지: 고의로 발생시켰음
 java.lang.Exception: 고의로 발생시켰음
       at Ex8_6.main(Ex8_6.java:4)
 프로그램이 정상 종료되었음

7.메서드 예외 선언하기 2: 예외문 떠넘기기(알리기)

- 메서드에 예외를 선언하려면, 메서드 선언부에 키워드 throws사용 -> 메서드 내에 발생가능한 예외를 기입

- 예외가 여러개일 시 쉼표로 구분

 void method() throws Exception1, Exception2, ExceptionN {
 // 메서드 내용
 }

throws: 앞 메서드에서 발생가능한 예외를 알림 (예외선언)

- 예외의 최고조상인 Exception클래스를 메서드에 선언할 시, 해당 메서드는 모든 종류의 예외가 발생 가능함을 의미

void method() throws Exception{
//메서드내용
}
class Ex8_9
  public static void main(String[] args) throws Exception {
    method();
  }
  
  static void method1() throws Exception{
    method2();
  }
  
  static void method2() throws Exception{
    throw new Exception();
  }
}