yoni

[18][OOP] 예외처리(Exception), throws 문 본문

java of educational by contents

[18][OOP] 예외처리(Exception), throws 문

yoni-1117 2018. 12. 2. 14:37

[01] 예외처리(Exception) 
     1) 이클립스상에서 개발시에 자바 클래스가 안정적으로 컴파일된 후
        운영중에 발생하는 에러를 "예외"라고 한다. 
        예외는 코드상에서 발생하는 에러하고는 다르며 컴파일시에는
        예외가 발생하지 않음. 
        마치 손상된 USB를 읽어오는 프로그램이 있다면 USB는 인식이되나
        읽어 올 수 없음으로 경고창이 발생하는 경우.

        예) 네트웍 장애, IO, DBMS 서버 다운, 저장 장치의 용량이 없는 경우등. 

     2) 예외가 발생하면 프로그램이 메시지 출력후 종료되어 심각한 문제가 발생
        할 수 있으나 예외 처리를 하면, 예외가 발생되서 프로그램이 끝나는 것이
        아니라 나머지 루틴이 정상적으로 실행됨으로 안정적인 프로그램이됨. 
 
     3) 기본 문법 
       
 
- finally 블럭은 생략 가능하나, 선언되면 예외 발생과 관련없이 무조건 실행됩니다.
  

--------------------------------------------------------------------

try{ 

   예외가 발생할 소지가 있는 코드를 개발자가 선별하여 지정해야하며,
   "JDBC(DBMS), IO, NETWORK"관련 코드등에서 발생하는 예외는 Eclipse가 알려줍니다.
   예) JDBC(DBMS): 데이터베이스 서버가 다운된 경우. 
        IO: USB 저장 장치가 여분이 없을 때 
        NETWORK: Hub에 이상이 생긴 경우, WiFi 작동 안됨.  

}catch(Exception e){ 
    예외 원인 출력, 예외 처리 
    Exception e 객체에는 발생한 예외의 정보를 가지고 있습니다. 
    System.out.println(e.toString()); 

    예외가 발생되기까지의 메소드 호출 이력을 추적하여 출력합니다. 
    e.printStackTrace(); 

    Log의 대상이 되어 파일로 기록 되어 서버 관리자가 체크함. 

    예) 데이터베이스 연결 종료 후 다른 서버로 재설정하며 원인 기록, 
         네트워크 연결 해제 후 다른 네트워크 장치 활성화하고 원인 기록, 
         WIFI 종료후 3G 작동 및 LTE작동 등 관련 데이터 기록  

}finally{ 
    예외와 상관 없이 무조건 실행되는 코드 블럭, 생략 가능 
    예) 데이터베이스 연결 종료 후 메모리 해제, 
        네트워크 연결 해제 후 메모리 해제, 
        WIFI 종료후 3G 작동 및 LTE작동 등의 필수 기능 



* Eclipse는 자바 개발자의 예외 처리를 가이드하는 기능이 있어서,
  예외 처리가 필요한 부분은 Eclipse가 알려주고 관련 코드도 자동 생성합니다.
--------------------------------------------------------------------


1. 예외가 발생되는 경우, 예외 처리 안한 경우
   - cmd 창에서 '총점, 과목수' 2개의 정수를 입력받아 형변환하여 출력하세요.
 
[실행 화면]

/oop/bin>java oop2.Ex1 250 3

총점: 250
과목수: 3

평균: 83 

/oop/bin>java oop2.Ex1 250 0
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at oop2.Ex1.main(Ex1.java:9)

 

▷ Ex1.java

-----------------------------------------------------------------------------------
package oop2;
 
public class Ex1 {
 
  public static void main(String[] args) {
    int tot = Integer.parseInt(args[0]);
    int cnt = Integer.parseInt(args[1]);
    
    int avg = tot / cnt;
    
    System.out.println("총점: " + tot);
    System.out.println("과목수: " + cnt);
    System.out.println("평균: " + avg);

    System.out.println("진행을 계속합니다.");
    avg =avg + 10;
    System.out.println("평균 추가 점수 부여: " + avg);
 
  }
 
}
 
 
-----------------------------------------------------------------------------------


[과제] cnt 변수(분모)로 0이 입력되면 '0으로 나눌 수 없습니다.'를 출력하고
종료하는 프로그램을 작성하세요.
- 종료: System.exit(0);

-----------------------------------------------------------------------------------
package oop2;
 
public class Ex1 {
 
  public static void main(String[] args) {
    int tot = Integer.parseInt(args[0]);
    int cnt = Integer.parseInt(args[1]);

     if (cnt == 0){
       System.out.println("0으로 나눌 수 없습니다.");
       System.exit(0);
     }
    int avg = tot / cnt;
    
    System.out.println("총점: " + tot);
    System.out.println("과목수: " + cnt);
    System.out.println("평균: " + avg);

    System.out.println("진행을 계속합니다.");
    avg =avg + 10;
    System.out.println("평균 추가 점수 부여: " + avg);
 
  }
 
}
 
 
 
 
-----------------------------------------------------------------------------------

 
 
2. 예외를 처리한 경우
    - 예외가 발생해도 프로그램은 계속 실행됩니다.

[실행 화면]


/ws_java/oop2/bin>java oop2.Ex2 250 3
총점: 250
과목수: 3
평균: 83
진행을 계속 합니다.
평균 추가 점수 부여: 93
 
/ws_java/oop2/bin>java oop2.Ex2 250 0
java.lang.ArithmeticException: / by zero
        at oop2.Ex2.main(Ex2.java:11)
진행을 계속 합니다.
평균 추가 점수 부여: 10
 
 

▷ Ex2.java 
-----------------------------------------------------------------------------------

package oop2;
 
public class Ex2 {
 
  public static void main(String[] args) {
    int tot = 0;
    int cnt = 0;
    int avg = 0;
    
    try {
      tot = Integer.parseInt(args[0]);
      cnt = Integer.parseInt(args[1]);
      avg = tot / cnt;
      
      System.out.println("총점: " + tot);
      System.out.println("과목수: " + cnt);
      System.out.println("평균: " + avg);
      
    } catch (Exception e) {
      String msg = e.toString();
      System.out.println("예외 발생: " + msg);
    } finally {
      System.out.println("진행을 계속합니다.");
      avg = avg + 10;
      System.out.println("평균 추가 점수 부여: " + avg);
    }
  }
}
 
 
  
-----------------------------------------------------------------------------------
 
 


3. NullPointerException [중요] 
   - 객체를 생성하지않고 객체의 값이 null인 상태에서 메소드나 변수를 호출한 경우
     NullPointerException이 발생합니다. (null: 메모리를 할당 받지 못한 상태, new가 실행 안됨) 
     이런 경우는 흔히 개발자의 판단 실수로 발생함으로 꼼꼼한 코드 테스트가 필요합니다. 
   - null: 메모리를 할당받지 못한 상태, 실행 불가능, 필드나 메소드를 호출 할 수
     없습니다. 

[실행 화면]


str: null    <-- test1() method
Exception in thread "main" java.lang.NullPointerException
at oop2.ExceptionTest.test1(Ex3.java:7)
at oop2.Ex3.main(Ex3.java:26)

str: null    <-- test2() method
java.lang.NullPointerException
        at oop2.ExceptionTest.test2(Ex3.java:14)
        at oop2.Ex3.main(Ex3.java:29)
에러 원인 로그 파일에 기록됨
다음 코드 계속 실행


str: null    <-- test() method
예외 무시후 로직 계속 실행
 

▷ ExceptionTest.java 

-----------------------------------------------------------------------------------
package oop2;
 
public class ExceptionTest {


 
 
}
 
 
-----------------------------------------------------------------------------------
 
▷ Ex3.java 
-----------------------------------------------------------------------------------
package oop2;
 
public class Ex3 {
 
  public static void main(String[] args) {
    ExceptionTest test = new ExceptionTest();
    // test.test1();
    // test.test2();
    // test.test3();
    
  }
 
}
 -----------------------------------------------------------------------------------
 
package oop2;
 
public class ExceptionTest {
  public void test1() {
    String str = null; // 메모리에 변수명만 존재
    System.out.println("str: " + str);
    System.out.println("str.length(): " + str.length()); // java.lang.NullPointerException 
    
  }
 
  public void test2() {
    try {
      String str = null; // 메모리에 변수명만 존재
      System.out.println("str: " + str);
      System.out.println("str.length(): " + str.length()); // java.lang.NullPointerException 
      
    } catch (Exception e) {
      System.out.println("예외 발생 기록: " + e.toString());      
    }
    
    System.out.println("시스템 정상 실행중...");
    
  }
  
  public void test3() {
    try {
      String str = null; // 메모리에 변수명만 존재
      System.out.println("str: " + str);
      System.out.println("str.length(): " + str.length()); // java.lang.NullPointerException 
      
    } catch (Exception e) {
      //예외 관련 작업 없음, 무시
    }
    
    System.out.println("시스템 정상 실행중...");
    
  }
  
}
 
 
 
-----------------------------------------------------------------------------------
 
 

4. throws 문의 사용
   - 일반적으로 예외는 Class 내부에서 처리하나, 다른 클래스가 예외를 처리하도록
     예외를 보내는 선언문
   - throws는 예외를 현재 메소드에서 처리하지 않겠다는 의도로
     try ~ catch를 사용할 필요가 없습니다.
   - 메소드를 호출한 다른 클래스의 메소드가 예외를 처리하겠다는
     의도를 명시적으로 선언한 것임. 
 

[실행 화면]

▶ Ex4Use에서 예외 잡음.
java.lang.ArithmeticException: / by zero
        at oop2.Ex4.calc(Ex4.java:6)
        at oop2.Ex4Use.main(Ex4Use.java:10)
나머지 루틴 정상 실행
------------------------------------------------
▷ Ex4Use에서 예외 잡음.
java.lang.ArithmeticException: / by zero
        at oop2.Ex4.calc2(Ex4.java:12)
        at oop2.Ex4Use.main(Ex4Use.java:19)
나머지 루틴 정상 실행
------------------------------------------------


▷ Ex4.java
- new java.util.Date().toLocaleString()
  . java.util 처럼 패키지를 클래스앞에 명시하면 import 선언이 필요 없습니다.
  . 메소드를 한번만 호출한다면 객체 이름이 없는 무명 객체를 생성 할 수 있습니다.
-----------------------------------------------------------------------------------
package oop2;
 
public class Ex4 {
  public void calc(int tot, int cnt) {
    int avg = tot / cnt;
    
    System.out.println("avg: " + avg);
  }
  
  // 현재 메소드에서 예외를 처리하지않고,
  // 예외 발생시 호출한 쪽으로 전달
  public void calc2(int tot, int cnt) throws Exception {
    int avg = tot / cnt;
    
    System.out.println("avg: " + avg);
  }
}
 
 
 
-----------------------------------------------------------------------------------
 

▷ Ex4Use.java 
-----------------------------------------------------------------------------------

package oop2;
 
public class Ex4Use {
 
  public static void main(String[] args) {
    Ex4 ex4 = new Ex4();
    // ex4.calc(210,  0);
    
    try {
      // try 문에서 메소드를 호출하면 throws가 없어도
      // 자동으로 예외가 전달되어 잡힘.
      ex4.calc(210,  0);
    } catch (Exception e) {
      System.out.println("▶ Ex4Use에서 예외 잡음.");
      e.printStackTrace();
    }
    System.out.println("나머지 루틴 정상 실행");
    System.out.println("----------------------------------------------");
 
    try {
      ex4.calc2(230,  0);
    } catch (Exception e) {
      System.out.println("▷ Ex4Use에서 예외 잡음.");
      e.printStackTrace();
    }
    System.out.println("나머지 루틴 정상 실행");
    System.out.println("----------------------------------------------");
  
  }
 
}
 
 
 
-----------------------------------------------------------------------------------
 
  
5. 시스템에 내장된 다양한 예외의 사용
[실행 화면]

C:\ai3\ws_java\oop\bin>java oop2.Ex5
예외가 발생했습니다.
데이터 처리중입니다...
 
C:\ai3\ws_java\oop\bin>java oop2.Ex5 0
0으로 나눌 수 없습니다.
데이터 처리중입니다...
 
C:\ai3\ws_java\oop\bin>java oop2.Ex5 영
정수를 입력하세요. 예) 1 ~
데이터 처리중입니다...
 
C:\ai3\ws_java\oop\bin>java oop2.Ex5 3
객체가 생성되지 않았습니다.
데이터 처리중입니다...
 
▷ Ex5.java 
-----------------------------------------------------------------------------------

package oop2;
 
public class Ex5 {
 
  public static void main(String[] args) {
    try {
      int year = Integer.parseInt(args[0]);
      int avg = 2017 / year;
      
      String str = null;
      System.out.println(str.toLowerCase());
      
    } catch (NumberFormatException e) {
      System.out.println("정수를 입력하세요. 예) 1 ~ ");
    } catch (ArithmeticException e) {
      System.out.println("0으로 나눌 수 없습니다.");
    } catch (NullPointerException e) {
      System.out.println("객체가 생성되지 않았습니다.");
    } catch (Exception e) {
      System.out.println("예외가 발생했습니다.");
    }
    
    System.out.println("데이터 처리중입니다...");
 
  }
 
}
 
 
 
-----------------------------------------------------------------------------------
  
 


Comments