Java

18 [인강] 자바의정석 ch08

Rosie_dev 2020. 12. 29. 20:31

| 프로그램 오류, 예외 클래스의 계층구조

  컴파일에러

  런타임에러: error 심각한 오류 - OOME(out of memory error)

                 exception

                 1) 사용자 실수 등으로 발생, 2) 프로그래머의 실수로 발생 (RuntimeException)

  논리적에러: 작성의도와 다르게 동작


| 예외처리하기, try-catch문의 흐름

  class Ex8_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.println(5);

        } 

  }


 class Ex8_2 {

     public static void main (String args[ ]) {

              System.out.println(1);

              try {

                  System.out.println(0/0);           //예외 발생

                  System.out.println(2);              //예외 발생시, catch블럭으로 넘어가므로 출력안됨

               } catch (ArithmeticException ae) {              

                     System.out.println(3);

               }

              System.out.println(4);

        } 

  }


  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) {                      //해당되므로 다음 catch블럭 건너뜀

                 if (ae instanceof ArithmeticException");

                    System.out.println("true");

                System.out.println("ArithmeticException");

                } catch (Exception e) {                                    //모든 예외의 최고조상

                    System.out.println("Exception");  

               }

              System.out.println(6);

        } 

  }


| printStackTrace(), 멀티 catch블럭

  예외객체가 만들어짐

  참조변수 ae의 유효범위 scope

  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 (ArithmenticException ae) {

                    ae.printStackTrace();

                    //java.lang.ArithmethicException: /by zero at Ex8_5.main(Ex8_5.java:8)

                    System.out.println("예외메시지: "+ae.getMessage());

                    //예외메시지: / by zero

             }

            System.out.println(6);

        }

  }   


  멀티 catch블럭

  try {

    .........

  } catch (Exception A | ExceptionB e) {

                      e.printStackTrace();

  //부모, 자식 관계는 안 됨, 그냥 부모타입 참조변수만 선언해도 해결

  //Exception A에만 해당하는 e.methodA(); 호출하면 에러, 공통멤버만 가능 

  //instanceof 형변환 후 사용가능

    if(e instanceof ExeptionA) {

           ExceptionA e1 = (ExceptionA)e;

           e1.methodA(); 


| 예외발생시키기

  Exception e = new Exception("고의");

  throw e;

  //catch블럭없으면, 비정상종료


  checked 예외

  unchecked 예외: 예외처리가 선택, try-catch문 없어도 컴파일에러는 없음, 런타임에러로 발생


| 예외선언하기, finally블럭

  예외처리법: try-catch문, 예외선언하기(떠넘기기), 은폐(빈catch블럭)

  void method() throws Exception { }     //예외선언, 모든 예외임에 유의

  *오버라이딩

   선언부일치 / 접근제어자좁게 설정 안 됨 / 조상보다 많은 예외선언 안 됨

 

  wait 메서드 사용시, throws 부분의 두가지 예외처리 필요

  but InterruptedException만 예외처리 필수!                                         //Java API문서

  

  class Ex8_9 {

        public static void main(String[] args) throws Exception {       

              method1();

        }

        static void method1() throws Exception {

              method2();

        static void method2() throws Exception {

              throw new Exception();

        }

  }

  //main에서 넘어간 예외는 JVM예외처리기에서 출력 (예외발생당시의)


    import java.io.*;

    class Ex8_10 {

         public static void main(String[] args) {

               try {

                   File f = createFile(args[0]);                   //문자열로 입력된 args[0]

                   System.out.println(f.getName()+"파일이 성공적으로 생성되었습니다.");

                  catch (Exception e) {

                  System.out.println(e.getMessage()+"다시 입력해 주시기 바랍니다.");

               }

          }

          static File createFile(String fileName) throws Exception {                     //파일생성, 에러선언 main으로 넘김

               if (fileName == null || fileName.equals(""))

                    throw new Exception("파일이름이 유효하지 않습니다.");

               File f = new File(fileName);                          //File 클래스의 객체를 만든다

               f.createNewFile();                                       //객체의 creatNewFile메서드를 활용해 실제 파일생성

               return f;                                                   //생성된 객체의 참조를 반환

           }

  }


  finally

  예외발생여부와 상관없이 수행되어야 하는 코드 작성

  try-catch문 하단에 작성

try {
    startInstall();
    copyFiles();
    deleteTempFiles();
  } catch (Exception e) {
        e.printStackTrace();
        deleteTempFiles();
  }

try {
    startInstall();
    copyFiles();
  } catch (Exception e) {
        e.printStackTrace();
  } finally {
        deleteTempFiles();
  }
  //중복제거

  


| 사용자정의 예외만들기, 예외되던지기

  조상은 Exception과 RuntimeException중에서 선택

  class MyException extends Exception {

        MyException (String msg) {

               super(msg);                        //조상의 Exception클래스의 생성자 호출


  예외되던지기

  예외를 처리한 후에 다시 예외를 발생시키는 것, 양쪽에서 처리

  public static void main(String[] args) {

       try {

          method1();

       }  catch (Exception e) {

            System.out.println("main메서드에서 예외가 처리되었습니다.");

       }

  }

  static void method1() throws Exception {

        try {

           throw new Exception();

        } catch (Exception e) {

            System.out.println("method1메서드에서 예외가 처리되었습니다.");

            throw e;

        }

  }


| 연결된 예외

  한 예외(원인예외)가 다른 예외를 발생시킬 수 있음

  public class Throwable implements Serializable {            //Throwable은 Exception, Error의 조상

         .....

      private Throwable cause = this;                              //객체 자신(this)를 원인예외로 등록

         .....

      private synchronized Throwable initCause(Throwable cause) {            //다른 예외를 포함, 연결된 예외

         .....

               this.cause = cause;

               return this;

      }         .....

  } 


  void install() throws InstallException {

       try {

           startInstall();

           copyFiles();

       } catch (SpaceException e) {

          InstallException ie = new InstallException("설치중 예외발생");           //예외생성

          ie.initCause(e);                          //InstallException의 원인예외를 SpaceException으로 지정

          throw ie;

      } catch (MemoryException me) {

         .....


  1.  catch 블럭이 너무 디테일하므로 하나의 catch블럭에 연결된 예외를 작성해서 다루기 위함

  → InstallException에다가 SpaceException, MemoryException 포함

  2. checked 예외를 unchecked 예외로 변경하려 할 때

  → try-catch 코드 작성으로 코드만 불필요하게 길어질 수 있음

  static void startInstall() throws SpaceException {

     if(!enoughSpace())

          throw new SpaceException("설치할 공간이 부족합니다.");

     if(!enoughMemory())

          throw new RuntimeException (new MemoryException("메모리가 부족합니다."));

  }       //RuntimeException의 원인예외로 MemoryException 등록

 

'Java' 카테고리의 다른 글

[Java] 데이터와 변수  (0) 2021.01.07
Java 별찍기 문제  (0) 2021.01.03
17 [인강] 자바의정석 ch07  (0) 2020.12.28
16 [인강] 자바의정석 ch07  (0) 2020.12.28
15 [인강] 자바의정석 ch07  (0) 2020.12.23
댓글