2020.10.31 생활코딩 유투브 공부 ( 모든 출처 : 유투버 생활코딩 ) 2 부 121 ~ exception

예외  EXCEPTION 


예외, 보안 : 실패하지 않는 법 


오류 -> 예외의 일종 


-뒷수습 

try { }

catch(exception e ) 

 {}


뒷수습의 방법 

try {~~~~~ }

catch(exception e ) 

 {

    System.out.println("\n\ne.getMeggage()\n" + e.getMessage() ) ; 

    System.out.println("\n\ne.toString()\n" + e.toString() ) ; 

    System.out.println("\n\ne.printStacTrace()\n" ) ;

    e.printStackTrace();   -> 이유가 나오게 하는 역할인거같아....!!

}

System.out.println("Divide End" ) ;   //예외가 발생되면 catch 안에 있는 애들을 실행시키고 컴퓨터가 멈추는 것이 아니라 그 뒤에를 계속 실행해준다. 이부분이 실행된다. 



java : 예외 ( 4/12 ) : 다양한 예외들과 다중캐치 



다중캐시 사용 


try { }

catch(ArithmeticException e ) {

    

}


catch(ArrayIndexOutOfBoundsException e) {

}


catch(Exception e ) { --> Exception e 가 만약 제일 위에 (catch 중에 제일 위에 오면 그 밑에 나머지 catch(ArithmeticException e ) 예외들은 실행이 안된다. 왜냐면 Exception 이 가장 상위이기 때문에 가장 위에 쓰면 밑에 있는 여러 예외들의 else if 격의 것들이 실행이 안된다. 

}


예외 ( 5/12) : finally 

try { 

} catch {

} finally {

예외여부와 관계없이 실행되는 로직 . try catch 문과 상관없이 언제나 실행되는 부분 

}

데이터베이스랑 연결할때 예외가 발생했을때 finally 에서 언제나 반드시 자바와 데이터베이스와의 접속을 끊는 코드를 작성해준다. -> 접속을 에러가 발생했을때 계속 물고 있는 경우 -> 100개만 접속가능하다고 할때 정상적접속 애플리케이션도 접속을 못하게 될 수도 있다. 

 

예외 (6/12) : 예외의 강제 

어떠 예외는 반드시 처리해야하도록 강제하는 예외가 있고 그렇지 않은 경우도 있다. 

Throws 뒤에 있는 내용 : 내용으로 인해서 오류가 생길 수 있다. 

예외처리를 강제해야 한다. 



try{  String input = null;

}catch{

}


try{  여기서 input 을 사용할 수 없다. 

}catch{

}


예외 ( 7/12) : 예외 사슬 


new FileReader("out.txt") FileReader 라는 api 를 사용하려고 할때 out 이라는 이름의 파일이 없을때 읽어올 수 없기 때문에 try catch 를 사용해서 오류가 나는 것을 방지한다.  ( api가 우리에게 예외를 throws 를 했다면 그것을 다른사람에게 넘길 수 있다. 


일반사용자에게 오류를 Throws 하면 오류가나면 예외처리하지 않고 그냥 프로그램을 종료시키겠다.  

다음사용자에게 Throws 하는것. 


예외 ( 8/12 ) : 책임의 전가 throws  : catch 는 자기가 처리하는 것이고 , throws 는 상대방에게 에러를 넘기는것


class B {

    void run() throws FileNotFoundException , IOException 

    //FileNotFoundException 예외에 강제하는것

    //여기있던 try catch 문 을 삭제하고 run() 뒤에 위에 처럼 써주면 밑에서 

    처리를 해줘야한다.(run() 을 호출한 곳에서 ) 

}

class C {

    void run () throws FileNotFoundException, IOException { 

        B.b = new B () ; 

      /*  try {

            b.run(); 

        }catch (FileNotFoundException e)  {

                 e.printStackTrace() ;    

        }catch ( IOExceptione ) { 

            e.printStackTrae(); 

        }   / 위에 run () throws ~~ 써주면 다른곳에(여기서는 밑에 class)  책임전가. 파랑글씨 try catch 지워주면됨 */ 

    

}


public classThrowExceptionDemo { 

    public static void main (String[] args ) { 

           C c = new c() ; 

         try {    //위에 파랑색인 애를 사용자에게 책임을 전가함 

        c.run() ; 

        } catch ( FileNotGoundException e ) { 

            e.printStacTrace () ; 

        } catch ( IOException e ) { 

            e.printStacTrace() ;

        } 


예외 ( 9/12 ) : 예외 만들기 

주체적으로 예외를 처리해보자 Exception 을 직접 발생시키는 법 

class Calculator { 

    int left, right ; 

    public void setOprands ( int left, int right ) { 

        if ( right == 0 ) { 

            throw new IllegalArgumentException ("두번째 인자는 0 을 허용하지                 않습니다.") ; 

        }

        

        //IllegalArgumentException 

        this.left = left; 

        this.right = right; 

}

    public void divide() { 

        if( right == 0 ) {

            throws new ArithmeticException ( " 0 으로 나눌 수 없습니다. " ) ;  

        } 

        //ArtithmeticException 

        try { 

       }catch (Exception e ) { 

        }

 }

}

public class CalculatorDemo { 

    public static void main(String[] args ) { 

        Calculator c1 = new Calculator () ; 

        c1.setOprands ( 10  , 0 ) ; 

         c1.divide() ; 

       /*  try { c1.divide() ; 

         }

        catch (ArithmeticException e ) { 

                System.out.println(e.getMessage()) ;   //getMessage() 는 위에 있는 

         ("0으로 나눌 수 없습니다.") ;  에 해당한다. 이 보라색 설명은 아래에 

        }      */  

-내용 참고  : https://www.youtube.com/watch?v=ZYC2oMzB-WU&list=PLuHgQVnccGMCeAy-2-llhw3nWoQKUvQck&index=129&ab_channel=%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9

 

보라색 설명

CalculatorDemo 클래스에서 setOprands 메소드를 호출하면 ( 10, 0 ) 을 넣고 그 두 divide() 를 실행하면  Calculator 클래스에 가서 divide() 메소드에서 if 문을 만나고 == 0 이기 때문에 거기서 멈추고 다시 CalculatorDemo 클래스로 온다. catch 문이 실행되고 ArithmeticException e 변수에 저장된다. (throws new ArithmeticException ( " 0 으로 나눌 수 없습니다. " ) ; ) 그다음 다시 calculator() 메소드로 돌아와서 출력이 e에 있는 메소드 getMesage() 를 출력하는데 이 메세지는 아까 우리가 저장한   (throws new ArithmeticException ( " 0 으로 나눌 수 없습니다. " ) ; )  이 부분에서 그 메세지부분인 보라색 부분이 출력이 되게 된다.  따라서  System.out.println(e.getMessage()) ;  를 하게 되면 보라색 부분이 출력이 되는 것이다. 


보충 설명 : throws new ArithmeticException 말고 throw ArithmeticException 이라면 

catch 에는 catch(ArithmeticException e = new ArithmeticException ("0으로 나눌 수 없습니다. ); 로 바꿀 수가 있다. 그리고 e.getMessage() 하면 첫번째 인자값이 출력이 된다.  복잡하니까 , throw 부분의 ArithmeticException 대신에 new ArithmeticException("0으로 나눌 수 없습니다. ) 으로 바꾼것

} 쉽게 말하자면 : 본래 throw ArithmeticException; 한뒤에 catch 의 ArithmeticExcetion e = new ArithmeticException 을 갖고 코드를 실행할 것을 편의상 변경한것이 위에 있다. 


-자바의 Exception 종류 


IllegalArgumentException 매개변수가 의도하지 않은 상황을 유발할때 

IllgalStateException : 메소드를 호출하기 위한 상태가 아닐 때

    동작할 수 있는 상황을 충족시키지 못할때 

NullPointExeption 매개 변수 값이 null 일 때 

ArthisticException 산술적인 연산에 오류가 있을 때 

IndexOutOfBoundsException 인덱스 매개 변수 값이 범위를 벗어날 때 


예외 ( 10/12 ) : 예외의 여러가지 상황들 


import java.io.IOExcption; 


class E { 

    void throwArithmeticException() { 

           throw new ArithmeticException() ; 

    }

    void throwIOException () { 

        throw new IOException() ;   컴파일이 안된다.  아리스메틱은 괜찮은데 why  얘만? 

    }

    void throwIOException2 () { 

        throw new IOException(); 

}                                                          


예외 ( 11/ 12 ) : checked unchecked 

예외의 선조 Throwable  ( 공통된 조상 ) 


한가지 예 )

clss ArithmeticException 

java.lang.Object 6`    

    java.lang Throwable 

        java.lang.Exception

            java.lang.RuntimeException

                java.lang.ArithmeticException 








조상Throwable

1.Error : 메모리가 너무 적을때 생김, 프로그램이 로지컬하게 할 수 있는 부분이 없고, 메모리를 효율적으로 짜거나 컴퓨터의 하드웨어를 업그레이드하는 등으로 해결해야함 

2. Exception 


    2-1 IOEXception  -> 예외를 처리하지 않으면 컴파일조차되지않는다. 

    2-2 RuntimeException

            2-2-1 ArithmeticException

부모중에 RuntimeException 이 있냐 없느냐에 따라서 IOEXeption 과 ArithmeticException 의 차이를 만든다. 

RuntimeException 이 있으면 unchecked exception -> 

처리하지 않아도 된다.

RuntimeExcetion 이 없으면 chedcked exception -> 

반드시 try-catch 나 throw 로 처리를 해줘야 한다. 



IOException checked exception : 반드시 예외처리가 존재해야한다. ( try catch or throws ) 


예외 ( 12/12 ) : 사용자 정의 예외 


표준예외 클래스를 사용하는 것을 권장한다. 


 


자신이 만들고자하는 것이 unchecked 인지 checked 인지를 생각한다. 


그 상황을 개선할 수 있는 여지가 있는 경우 : checked exception 을 사용한다.

(try catch , throw ) 

그 상황에서 어플리케이션을 종료해야 하는게 더 낫거나 사용자가 에러에 대해서 할 수 있는게 많이 없다 : unchecked exception 을 사용한다.


ex) 

ArithmeticException 은 산술적인 문제 -> 계속 영향을 줄 수 있어서 unchecked exception 으로 사용해서 끝내버린다. 

ex) 

파일이 없는경우 -> 사용자가 파일을 다시 찾아서 할 수 있다. -> 복구가 가능하다. checked exception 으로 try-catch 나 throws  처리를 한다. 


예시 ) 

class DivdeException extends RuntimeException {  //checked 냐 unchecked 냐에 따라서 상속되는애가 달라져야 함 얘는 unchecked exception 으로 해줌 

//class DivdeException extends ArithmeticException 으로 하면 산술과 관련된 예외지만  좀 더 특화된 용도로 사용할 수 있다. . 

//class DivdeException extends Exception  -> checked exception 하면 예외처리 뒤에 해줘야함 안그러면 밑에 컴파일 오류가 생김 

    DivdeException () {  //기본생성자 만들어줌 

        super () ; 

  

    }

    DivdeException(String message ) { 

        super(message) ; 

        }     부모클래스의 생성자를 호출할때 message 를 주려고 .   //우리가 만들어주고 싶은 생성자를 만드는데 기본생성자와달라서 자바가 기본 생성자를 자동으로 생성해주지 않는다. 그래서 위에 기본 생성자도 만들어줌

}     


class Calculator { 

    int left, right ; 

    public void setOprands ( int left, int right ) { 

        this.left = left; 

        this.right = right; 

    } 

}

    public void divide() { 

       

        if(right == 0 ) { 

            throw new DivdeException// 으로 변경 뒤에 아리스 없애고 우리가 만들어준 예외로 교체ArithmeticException ( " 0 으로 나눌 수 없습니다. " ) ; 

            }    System.out.pritnln(this.left/this.right ) ; 

        } 

            //이렇게 밑에처럼 예외처리를 해줘야 함 안그러면 컴파일 오류

             try { 

                if(right == 0 ) { 

                    throw new DivdeException ( "0으로 나눌 수 없습니다. " ) ; 

                    } 

                    System.out.print(this.left/ this.right ) ; 

                } catch ( DivideException e ) { 

                    e.printStackTrace() ; 

                

                3번째 방법

    public void divide () throws DivideException {  //  api 의 사용자에게 책임전가 얘를 호출하는 main 부분을 고쳐줘야함 

         if(right == 0 ) {  

                throw new DivdeException// 으로 변경 아리스 없애고 교체                                ArithmeticException ( " 0 으로 나눌 수 없습니다. " ) ; 

            }        

            System.out.pritnln(this.left/this.right ) ; 

        } 

           


public class CalculatorDemo { 

    public static void main(String[] args ) { 

        Calculator c1 = new Calculator () ; 

        c1.setOprands ( 10  , 0 ) ; 

        try { 

            c1.divide() ; 

        } catch ( DivideException e ArithmeticException e ) {  

            System.out.println(e.getMessage() ) ; 

        } 


실제로 정보들을 추가적으로 제공할 수 있다. ( 유투브 마지막부분 참고 ) 

: https://www.youtube.com/watch?v=Am5meHwYDWE&list=PLuHgQVnccGMCeAy-2-llhw3nWoQKUvQck&index=132&ab_channel=%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9 


























댓글