Dreaming Dean
Hello, I'm Studying
  • Secure
  • Java
  • Oracle
  • +others
Coding.
I AM STUDYING PROGRAMING LANGUAGE. IF YOU WANT TO SEE MY WORK THE PROGRAMMING PROJECT, CHECK IT OUT MY BLOG AND GITHUB.

Exception 예외

Dean92
2017. 6. 5. 01:24

오류Error

프로그램 구동 중 오작동을 일으키거나 비정상적 종료를 일으키는 원인을 오류라고 하는데 발생 시점에 따라 분류되는 컴파일 에러, 런타임 에러와 프래그래머의 의도와 다르게 동작하는 논리적 에러가 존재한다.



자바에서는 런타임시 발생할 수 있는 프로그램 오류를 에러Error와 예외Exception 두가지로 구분한다. 에러는 메모리 부족이나 스택오버플로우와 같이 발생하면 복구할 수 없는 심각한 오류들을 뜻하고 예외는 발생하더라도 프로그래머가 작성한 예방 코드로 수습될 수 있는 덜 심각한 오류를 뜻한다.

오류Error   수습될 수 없는 심각한 오류
예외Exception   수습될 수 있는 오류
"오류는 어쩔 수 없지만 예외는 반드시 처리해야 한다."


예외처리

  • 나이를 입력받는데 0보다 작은 값이 입력되었다.
  • 나눗셈 계산을 위해 두개의 정수를 입력 받는데 나누는 수로 0이 입력되었다.
  • 주민등록번호 숫자13자리를 입력 받는데 중간에 ‘-’를 포함한 14자리를 입력 받았다.
  • 위와 같이 프로그램의 실행 도중에 발생하는 문제 상황을 예외라고 한다. 예외는 컴파일 오류같이 문법오류와는 의미가 다르다.

    예외처리Exception Handling
  • 정의 – 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성한다.
  • 목적 – 프로그램의 비정상 종료를 막고 정상적인 실행상태를 유지한다.
  • try-catch문

    예외를 처리하기위해 try-catch문을 사용한다.

    try {
    	// 예외 발생 가능성이 있는 코드가 들어간다.
    } catch (Exception1 e1) {
    	// Exception1이 발생했을 때 처리할 코드가 들어간다.
    } catch (Exception2 e2) {
    	// Exception2가 발생했을 때 처리할 코드가 들어간다.
    }
    	...
    } catch (ExceptionN eN) {
    	// ExceptionN이 발생했을 때 처리할 코드가 들어간다.
    }
    
    하나의 try 블럭다음에는 하나 이상의 catch블럭이 올수 있고 이중 발생한 예외 종류와 일치하는 단 하나의 catch블럭만 수행된다. 일치하는 블럭이 없으면 예외처리는 되지 않는다.
    	public static void main(String[] args) {
    		try {
    			try {
    
    			} catch (Exception e) {
    				// TODO: handle exception
    			}
    		} catch (Exception e) {
    			try {
    
    			} catch (Exception e2) {
    				// catch블럭 내에 또 다른 try-catch문이 포함된 경우
    				// 다른 이름의 참조변수(e1,e2)를 사용해야 한다.
    			}
    		}
    	}
    
    각 catch블럭 내의 두 참조변수 영역이 겹치므로 다른 이름을 사용해서 구별해 주어야 한다.
    try-catch문 실행순서
    - try 블럭 내에서 예외가 발생한 경우
  • 발생한 예외와 일치하는 catch블럭이 있는지 검사한다.
  • 일치하는 catch블럭이 존재하면 그 catch블럭 내의 문장들을 수행하고 전체 try-catch문을 빠져나와서 그 다음 코드들을 계속 수행한다. 만약 일치하는 catch블럭이 없다면 예외는 처리되지 않는다.
  • - try 블럭 내에서 예외가 발생하지 않은 경우
  • catch블럭을 거치지 않고 전체 try-catch문을 빠져나와 다음 코드를 수행한다.
  • 	public static void main(String[] args) {
    		System.out.println(1);
    		try {
    			System.out.println(2);
    		} catch (Exception e) {
    			System.out.println(3);
    		}
    		System.out.println(4);
    	}
    

    예외가 발생하지 않았으므로 catch블럭 내의 문장(3이 출력되지 않음)이 실행되지 않았다.
    	public static void main(String[] args) {
    		System.out.println(1);
    		try {
    			System.out.println(2);
    			System.out.println(100/0);	//예외를 발생시킴 catch블럭으로 이동
    			System.out.println(3);		//실행되지 않음
    		} catch (ArithmeticException ae) {
    			System.out.println(4);
    		}
    		System.out.println(5);
    	}
    

    try블럭에서 예외가 발생(100/0)했기 때문에 try블럭을 바로 벗어나서(3은 출력되지 않음) catch블럭으로 이동해 코드를 실행한 다음 전체 try-catch문을 벗어나서 5를 출력한다.


    예외처리 클래스

    자바는 실행 시 발생할 수 있는 오류를 클래스로 정의해 놓았다. 모든 클래스의 조상은 Object클래스이므로 Exception과 Error클래스 역시 Object의 자손이다.

    모든 예외의 조상은 Exception이다.

    RuntimeException 클래스들 – 프로그래머의 실수로 발생하는 예외(언체크 예외)
    Exception클래스들 – 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외(체크 예외)

    예외발생과 catch블럭

  • try블럭에서 예외가 발생하면, 발생한 예외를 처리할 catch블럭을 찾는다.
  • 첫번째 catch블럭부터 순서대로 찾아 내려가며, 일치하는 catch블럭이 없으면 예외는 처리되지 않는다.
  • 예외의 최고 조상인 Exception을 처리하는 catch블럭은 모든 종류의 예외를 처리할 수 있다.(반드시 마지막 catch블럭이어야 한다.)
  • 	public static void main(String[] args) {
    		System.out.println(1);
    		try {
    			System.out.println(2);
    			System.out.println(100/0);	//예외를 발생시킴
    			System.out.println(3);		//실행되지 않음
    		} catch (ArithmeticException ae) {
    			if(ae instanceof ArithmeticException) {
    				System.out.println("true");
    			}
    			System.out.println("ArithmeticException");
    		} catch (Exception e) {	// ArithmeticException을 제외한 모든 예외가 처리됨
    			System.out.println("Exception");
    		}
    		System.out.println(5);
    	}
    

    try-catch문의 마지막에 Exception클래스 타입의 참조변수를 선언한 catch블럭을 사용하면 어떤 종류의 예외가 발생 하더라도 이 catch블럭에 의해 예외가 처리될 수 있다.

    예외처리 클래스의 메소드

    예외처리 클래스의 특정 메소드를 사용하면 발생한 예외 객체를 catch블럭의 참조변수로 접근할 수 있다.

    printStackTrace() – 예외발생 당시의 호출스택(Call Stack)에 있던 메서드의 정보와 예외 메세지를 화면에 출력한다.
    getMessage() – 발생한 예외클래스의 인스턴스에 저장된 메세지를 얻을 수 있다.
    	public static void main(String[] args) {
    		System.out.println(1);
    		try {
    			System.out.println(2);
    			System.out.println(100/0);	//예외를 발생시킴
    			System.out.println(3);		//실행되지 않음
    		} catch (ArithmeticException ae) {
    			//참조변수 ae를 통해 생성된 ArithmeticException의
    			//인스턴스에 접근 가능
    			ae.printStackTrace(); 
    			System.out.println("Exception Message : " + ae.getMessage());
    		} 
    		System.out.println(5);
    

    printStackTrace() 와 getMessage()메소드를 통해 예외 발생 원인을 분석 할 수 있다.

    finally블럭

    finally블럭은 try-catch문과 함께 예외의 발생여부에 상관없이 코드가 실행되어야 할 때 사용한다.

  • 예외의 발생여부와 관계없이 실행되어야 하는 코드를 넣는다.
  • 선택적으로 사용할 수 있으며, try-catch-finally의 순서로 구성된다.
  • 예외 발생시, try → catch → finally의 순서로 실행되고
    예외 미발생시, try → finally의 순서로 실행된다.
  • try 또는 catch블럭에서 return문을 만나도 finally블럭은 수행된다.
  • 		try {
    			// 예외 발생 가능성이 있는 코드
    		} catch (Exception e) {
    			// 예외 처리 코드
    		} finally {
    			// 예외 발생 여부에 상관없이 동작하는 코드
    			// try-catch블럭은 맨 마지막에 위치함
    		}
    

    예외 던지기

    예외를 처리하는 방법에는 try-catch외에도 예외를 메소드에 선언하는 방법(예외 던지기)이 있다.

    void method() throws Exception1, Exception2, ... , ExceptionN {
     ...
    } 
    
    메서드 선언부에 throws를 사용하고 메소드 내에 발생하는 예외를 선언한다.
  • 예외를 처리하는 또 다른 방법이다.
  • 사실은 예외를 처리하는 것이 아니라, 호출한 메서드로 예외 처리 해야할 정보를 전달해주는 것이다.
  • 호출한 메서드에서 예외처리를 해야만 할 때 사용한다.
  • Comments