Java

예외 3 - 만들기

소비자에서 생산자로

지금까지 API의 소비자로서 API 측에서 던지는 예외를 처리하는 방법을 알아봤다. 이번에는 API의 생산자로서 소비자들에게 API를 제공하는 입장에 서보자. 전 시간에 사용했던 코드를 바탕으로 이야기를 풀어가자.

package org.opentutorials.javatutorials.exception;
class Calculator{
    int left, right;
    public void setOprands(int left, int right){
        this.left = left;
        this.right = right;
    }
    public void divide(){
        try {
            System.out.print("계산결과는 ");
            System.out.print(this.left/this.right);
            System.out.print(" 입니다.");
        } catch(Exception e){
            System.out.println("\n\ne.getMessage()\n"+e.getMessage());
            System.out.println("\n\ne.toString()\n"+e.toString());
            System.out.println("\n\ne.printStackTrace()");
            e.printStackTrace();
        }
    }
} 
public class CalculatorDemo {
    public static void main(String[] args) {
        Calculator c1 = new Calculator();
        c1.setOprands(10, 0);
        c1.divide();
    }
}

위의 코드에서 예외가 발생한 이유는 10을 0으로 나누려고 하기 때문이다. 즉 setOprands를 통해서 입력된 두번째 인자의 값이 0이기 때문에 발생한 문제다. 우리가 할 수 있는 조치는 두가지다.

  • setOprands의 두번째 인자로 0이 들어오면 예외를 발생시킨다.
  • 메소드 divide를 실행할 때 right의 값이 0이라면 예외를 발생시킨다.

첫번째 방법을 적용해보자.

package org.opentutorials.javatutorials.exception;
class Calculator{
    int left, right;
    public void setOprands(int left, int right){
        if(right == 0){
    		throw new IllegalArgumentException("두번째 인자의 값은 0이 될 수 없습니다.");
    	}
        this.left = left;
        this.right = right;
    }
    public void divide(){
        try {
            System.out.print("계산결과는 ");
            System.out.print(this.left/this.right);
            System.out.print(" 입니다.");
        } catch(Exception e){
            System.out.println("\n\ne.getMessage()\n"+e.getMessage());
            System.out.println("\n\ne.toString()\n"+e.toString());
            System.out.println("\n\ne.printStackTrace()");
            e.printStackTrace();
        }
    }
} 
public class CalculatorDemo {
    public static void main(String[] args) {
        Calculator c1 = new Calculator();
        c1.setOprands(10, 0);
        c1.divide();
    }
}

차이점

실행 결과는 아래와 같다.

Exception in thread "main" java.lang.IllegalArgumentException: 두번째 인자의 값은 0이 될 수 없습니다.
    at org.opentutorials.javatutorials.exception.Calculator.setOprands(CalculatorDemo.java:6)
	at org.opentutorials.javatutorials.exception.CalculatorDemo.main(CalculatorDemo.java:27)

두번째 인자의 값이 0이 되었을 때 setOprands의 사용자에게 예외 클래스인 IllegalArgumentException을 던지고 있다. 사용자인 main은 예외와 함께 '두번째 인자의 값은 0이 될 수 없습니다.'라는 메시지를 받게 되고 이 정보를 바탕으로 전달 값을 변경하게 된다.

아래와 같이 divide 내에서 예외를 처리할 수도 있다.

package org.opentutorials.javatutorials.exception;
class Calculator{
    int left, right;
    public void setOprands(int left, int right){        
        this.left = left;
        this.right = right;
    }
    public void divide(){
    	if(this.right == 0){
    		throw new ArithmeticException("0으로 나누는 것은 허용되지 않습니다.");
    	}
        try {
            System.out.print("계산결과는 ");
            System.out.print(this.left/this.right);
            System.out.print(" 입니다.");
        } catch(Exception e){
            System.out.println("\n\ne.getMessage()\n"+e.getMessage());
            System.out.println("\n\ne.toString()\n"+e.toString());
            System.out.println("\n\ne.printStackTrace()");
            e.printStackTrace();
        }
    }
} 
public class CalculatorDemo {
    public static void main(String[] args) {
        Calculator c1 = new Calculator();
        c1.setOprands(10, 0);
        c1.divide();
    }
}

차이점

throw는 예외를 발생시키는 명령이다. throw 뒤에는 예외 정보를 가지고 있는 예외 클래스가 위치한다. 자바 가상 머신은 이 클래스를 기준으로 어떤 catch 구문을 실행할 것인지를 결정한다. 또 실행되는 catch 구문에서는 예외 클래스를 통해서 예외 상황의 원인에 대한 다양한 정보를 얻을 수 있다. 이 정보를 바탕으로 문제를 해결하게 된다.

필자가 사용한 예외인 IllegalArgumentException, ArithmeticException은 자바에서 기본적으로 제공하는 예외다. 이러한 예외들은 자바 가상머신이 사용하기도 하고 또 응용 프로그램 개발자가 사용할 수도 있다. 기본적으로 제공되는 어떤 예외들이 있는지를 파악하고 적당한 예외를 사용하는 것은 중요한 문제다. 클래스 Exception을 API 문서에서 찾아보고 그 하위 클래스로 어떤 것들이 있는지 살펴보는 것도 도움이 된다. 다음은 기억할만한 주요 Exception들의 리스트다. (effective Java p338 참고)

예외 사용해야 할 상황
IllegalArgumentException 매개변수가 의도하지 않은 상황을 유발시킬 때
IllegalStateException 메소드를 호출하기 위한 상태가 아닐 때
NullPointerException 매개 변수 값이 null 일 때
IndexOutOfBoundsException 인덱스 매개 변수 값이 범위를 벗어날 때
ArithmeticException 산술적인 연산에 오류가 있을 때

예외의 여러가지 상황들

예외에 대한 시야를 넓히기 위해서 몇가지 상황들을 간단한 코드로 만들어 보았다.

package org.opentutorials.javatutorials.exception;
class E{
    void throwArithmeticException(){
		throw new ArithmeticException();
	}
}

문제없이 컴파일이 될 것이다. 이번엔 아래와 같이 코드를 바꿔보자.

package org.opentutorials.javatutorials.exception;
import java.io.IOException;
class E{
    void throwArithmeticException(){
		throw new ArithmeticException();
	}
	void throwIOException(){
		throw new IOException();
	}
}

차이점

이번에는 컴파일 되지 않을 것이다. 에러 내용은 아래와 같다. 왜 그럴까?

src\org\opentutorials\javatutorials\exception\ThrowExceptionDemo2.java:8: error: unreported exception IOException; must be caught or declared to be thrown
                throw new IOException();
                ^
1 error

에러에는 아래와 같이 적혀있다.

unreported exception IOException; must be caught or declared to be thrown

즉 IOException은 try...catch하거나 throw 해야 한다는 뜻이다.

이상하다 ArithmeticException, IOException 모두 Exception이다. 그럼에도 불구하고 유독 IOException만 try...catch 혹은 throw 를 해야 한다는 뜻이다. 자바는 이 두개의 예외를 다른 방법으로 대하고 있는 것이다. 우선 아래와 같이 코드를 변경해서 에러를 없애자.

package org.opentutorials.javatutorials.exception;
import java.io.IOException;
class E{
    void throwArithmeticException(){
		throw new ArithmeticException();
	}
	void throwIOException1(){
		try {
			throw new IOException();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	void throwIOException2() throws IOException{
		throw new IOException();
	}
}

차이점

예제의 핵심은 IOException은 예외처리를 강제하고 있지만 ArithmeticException은 그렇지 않다 점이다. 그 이유를 알아보자.

예외의 선조 - Throwable

우선 ArithmeticException의 API 문서를 통해서 예외들의 가계도를 살펴보자. 아래 그림은 API 문서의 일부를 캡처한 것이다.

이것을 통해서 ArithmeticException의 부모 클래스 중에 java.lang.Exception 클래스가 있다는 사실을 알 수 있다. ArithmeticException 클래스는 Exception 클래스의 하위 클래스였던 것이다. 그렇기 때문에 Exception 클래스가 더 많은 예외 상황을 포괄하는 것이고 ArithmeticException 클래스는 더 구체적인 상황을 특정하는 것이다. 잘 이해가 안 되면 이전에 소개했던 예제를 보자.

try {
    System.out.println(arr[first] / arr[second]);
} catch(ArrayIndexOutOfBoundsException e){
    System.out.println("ArrayIndexOutOfBoundsException");
} catch(ArithmeticException e){
    System.out.println("ArithmeticException");
} catch(Exception e){
    System.out.println("Exception");
}

그리고 상속 관계를 자세히 보면 java.lang.Throwable 클래스가 있다. 이 클래스를 클릭해서 Throwable 클래스의 페이지로 이동해보면 아래와 같은 내용을 발견할 수 있다.

우리가 지금까지 사용했던 getMessage, printStackTrace, toString이 Throwable 클래스에서 정의 되어 있었던 것이다! 또 이 클래스의 이름이 Throwable이다. '던질 수 있는'이라는 뜻이다. 즉 예외로 '던질 수 있는' 클래스는 반드시 Throwable 클래스를 상 받아야 한다.

예외의 종류

그럼 위에서 이야기한 것을 개념적으로 정리해보자. 우선 중요한 예외 클래스들은 아래와 같다.

  • Throwable
  • Error
  • Exception
  • Runtime Exception

이 클래스 간의 상속 관계를 그림으로 나타내면 아래와 같다.

 

Throwable

클래스 Throwable은 범 예외 클래스들의 공통된 조상이다. 모든 예외 클래스들이 가지고 있는 공통된 메소드를 정의하고 있다. 중요한 역할을 하는 클래스임에는 틀림없지만 이 클래스를 직접 사용하지는 않기 때문에 우리에게는 중요하지 않다.

Error

에러는 여러분의 애플리케이션의 문제가 아니라 그 애플리케이션이 동작하는 가상머신에 문제가 생겼을 때 발생하는 예외다. 애플리케이션을 구동시키기에는 메모리가 부족한 경우가 이에 속한다. 이런 경우는 애플리케이션 개발자가 할 수 있는 것이 없다. 따라서 예외처리를 하지 말고 그냥 에러로 인해서 애플리케이션이 중단되도록 내버려둔다. 대신 자신의 애플리케이션이 메모리를 과도하게 사용하고 있다면 로직을 변경하거나 자바 가상머신에서 사용하는 메모리의 제한을 변경하는 등의 대응을 한다.

Exception

결국 우리의 관심사는 Exception 클래스와 RuntimeException 클래스로 좁혀진다. 우선 Exception 클래스의 하위 클래스들의 목록을 살펴보자. 아래 클래스들은 모두 Exception 클래스를 상속한 예외 클래스다.

필자가 강조 표시한 부분을 보자. 저 많은 클래스 중의 하나가 RuntimeException이다. 도대체 RuntimeException 클래스는 어떤 특이점이 있길래 부모 클래스인 Exception 클래스와 함께 언급되는 것일까? RuntimeException을 제외한 Exception 클래스의 하위 클래스들과 RuntimeException 클래스의 차이를 자바에서는 checked와 unckecked라고 부른다. 관계를 정리하면 아래와 같다.

  • checked 예외 - RuntimeException을 제외한 Exception의 하위 클래스
  • unchekced 예외 - RuntimeException의 하위 클래스

checked 예외는 반드시 예외처리를 해야 하는 되는 것이고, unchekced는 해도 되고 안 해도 되는 예외다. 바로 이 지점이 IOException과 ArithmeticException의 차이점이다. 아래는 두개 클래스들의 가계도를 보여준다.

강조 표시한 부분을 주의 깊게 살펴보자. ArithmeticException의 부모 중에 RuntimeException이 있다. 반면에 IOException은 Exception의 자식이지만 RuntimeException의 자식은 아니다. 이런 이유로 IOException은 checked이고 ArithmeticException은 unchekced이다. (Error도 unchecked이다)

나만의 예외 만들기

표준 예외 클래스로도 많은 예외 상황을 표현할 수 있다. 하지만 그렇지 않은 경우도 있을 것이다. 이런 때는 직접 예외를 만들면 된다.

예외를 만들기 전에 해야 할 것은 자신의 예외를 checked로 할 것인가? unchecked로 할 것인가를 정해야 한다. 그 기준은 모호한 문제다. 하지만 기준이 없는 것도 아니다.

API 쪽에서 예외를 던졌을 때 API 사용자 쪽에서 예외 상황을 복구 할 수 있다면 checked 예외를 사용한다. checked 예외는 사용자에게 문제를 해결할 기회를 주는 것이면서 예외처리를 강제하는 것이다. 하지만 checked 예외를 너무 자주 사용하면 API 사용자를 몹시 힘들게 할 수 있기 때문에 적정선을 찾는 것이 중요하다.

사용자가 API의 사용방법을 어겨서 발생하는 문제거나 예외 상황이 이미 발생한 시점에서 그냥 프로그램을 종료하는 것이 덜 위험 할 때 unchecked를 사용한다.  기존의 ArithmeticException을 직접 만든 Exception으로 교체해보자.

package org.opentutorials.javatutorials.exception;
class DivideException extends RuntimeException {
    DivideException(){
		super();
	}
	DivideException(String message){
		super(message);
	}
}
class Calculator{
    int left, right;
    public void setOprands(int left, int right){    	
        this.left = left;
        this.right = right;
    }
    public void divide(){
    	if(this.right == 0){
    		throw new DivideException("0으로 나누는 것은 허용되지 않습니다.");
    	}
        System.out.print(this.left/this.right);
    }
}
public class CalculatorDemo {
    public static void main(String[] args) {
        Calculator c1 = new Calculator();
        c1.setOprands(10, 0);
        c1.divide();
    }
}

차이점

만약 DivideException을 Exception으로 바꾸면 어떻게 될까? 아래 코드의 RuntimeException을 Exception으로 변경하면 된다.

class DivideException extends RuntimeException {
class DivideException extends Exception {

아래와 같이 컴파일 에러가 발생한다.

src\org\opentutorials\javatutorials\exception\CalculatorDemo.java:18: error: unreported exception DivideException; must be caught or declared to be thrown
                throw new DivideException("0으로 나누는 것은 허용되지 않습니다.");
                ^
1 error

이를 해결하려면 두가지 방법이 있다. 하나는 예외처리를 하는 것이다. 문법을

package org.opentutorials.javatutorials.exception;
class DivideException extends Exception {
    DivideException(){
		super();
	}
	DivideException(String message){
		super(message);
	}
}
class Calculator{
    int left, right;
    public void setOprands(int left, int right){    	
        this.left = left;
        this.right = right;
    }
    public void divide(){
    	if(this.right == 0){
    		try {
				throw new DivideException("0으로 나누는 것은 허용되지 않습니다.");
			} catch (DivideException e) {
				e.printStackTrace();
			}
    	}
        System.out.print(this.left/this.right);
    }
}
public class CalculatorDemo {
    public static void main(String[] args) {
        Calculator c1 = new Calculator();
        c1.setOprands(10, 0);
        c1.divide();
    }
}

차이점

혹은 사용자에게 예외를 던진다. 사용자는 반드시 예외에 대한 처리를 해야 한다.

package org.opentutorials.javatutorials.exception;

class DivideException extends Exception {
    DivideException(){
		super();
	}
	DivideException(String message){
		super(message);
	}
}
class Calculator{
    int left, right;
    public void setOprands(int left, int right){    	
        this.left = left;
        this.right = right;
    }
    public void divide() throws DivideException{
    	if(this.right == 0){
    		throw new DivideException("0으로 나누는 것은 허용되지 않습니다.");
		}
        System.out.print(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) {
			e.printStackTrace();
		}
    }
}

차이점

예외는 오류 없는 애플리케이션을 만들기 위해서 꼭 필요한 기능이다. 동기부여는 덜 되겠지만 꼭 숙지하길 바란다.

댓글

댓글 본문
작성자
비밀번호
  1. 칼립소
    2차 정주행 완료
  2. Daydream
    좀 어려운말인것 같네요
    exception 으로 처리해도되지만 각 자세한 예외처리가 불가하고
    예외를 몽땅 간단하게 처리하려면 exception 으로 그냥 넘기기로 에러를 숨김.

    20181028 좋은강의 감사합니다.
  3. 좀 개소리같네요,,
    대화보기
    • 전하연
      감사합니다
      2018.8.30 20:44
    • 이태호
      7/15
      checked 예외 - RuntimeException을 제외한 Exception(본인포함)의 하위 클래스
      unchekced 예외 - RuntimeException(본인포함)의 하위 클래스
      checked 예외는 반드시 예외처리를 해야 하는 되는 것이고, unchekced는 해도 되고 안 해도 되는 예외다.
    • 초보입니다
      그냥 개인적인 생각이지만... (저도 시작한지 2주된 초보라 맞는지 틀린진 모릅니다만...)
      super를 두번쓰는 이유는
      if(this.right == 0){
      throw new DivideException("0으로 나누는 것은 허용되지 않습니다.");
      여기서 클래스 DivideException의 매소드 DivideException("0으로 나누는 것은 허용되지 않습니다.") 를 쓰는데
      ()안에 들어간게 문자열이므로 DivideException(String) 매소드를 문자들어간거, DivideException() 문자안들어간거 2개를 써야 합니다.. 문자가 안들어간다면 매소드가 자동생성되므로 굳이 쓸필요 없어 보이지만..
      객체언어이기 때문에 문자열이 들어간 매소드를 만들어야 한다면 같은 이름의 매소드를 하나 더 생성해야합니다.
      그래서 super를 두번쓰는게 아닌가 싶네요...^^;;
      대화보기
      • 김세창
        마지막강의와 그 위에 강의가.. 다시한번보고 이해해야할것같습니다..ㅠㅠ
      • ㅎㅎㅎ
        무슨말인지 알겠어여 완벽히 숙지하려면 코딩해보는게 답인것 같습니다.
      • 마로
        <저도 추가적질문...>


        package org.opentutorials.javatutorials.Inheritance.example3;
        class Calculator {
        int left, right;
        public Calculator(){}
        public Calculator(int left, int right){
        this.left = left;
        this.right = right;
        }
        public void setOprands(int left, int right) {
        this.left = left;
        this.right = right;
        }
        public void sum() {
        System.out.println(this.left + this.right);
        }
        public void avg() {
        System.out.println((this.left + this.right) / 2);
        }
        }
        class SubstractionableCalculator extends Calculator {
        public SubstractionableCalculator(int left, int right) {
        super(left, right);
        }
        public void substract() {
        System.out.println(this.left - this.right);
        }
        }
        public class CalculatorConstructorDemo5 {
        public static void main(String[] args) {
        SubstractionableCalculator c1 = new SubstractionableCalculator(10, 20);
        c1.sum();
        c1.avg();
        c1.substract();
        }
        }


        23강 예제 입니다. 이경우에는 자식클래스에서 파라메터값을 받는 생성자를 정의해 줬지만 부모클래스의 기본생성자를 초기화 시켜주지 않고 있습니다. 이렇게 하고도 에러없이 잘 실행됩니다.
        왜 그런거죠?
        이번시간 예제에서의 부모클래스인 RuntimeException에는 기본생성자와 파라메터값을 받는 생성자 둘다 선언되어 있을 텐데요.
        혹시 RuntimeException에는 23강의 예제처럼 기본 생성자가 자동적으로 정의되어 있지 않기 때문이지 않을가요?
      • 이현수
        부모클래스의 생성자가 인자를 받는다면 자식클래스에서 super 를 사용한다면 부모클래스의 기본생성자의 초기화는 하지 않아도 되는걸로 알고 있는데

        DivideException(){
        super();
        }
        이 부분에 대한 설명이 없어서 무슨말인지 모르겠네요
        기본생성자를 만들어주지 않아도 되는걸로 알고 있는데 반복하는 이유가 무엇인가요?
      • 하면된다하자
        감사합니다. 잘 들었습니다.
      • popinbompin
        완료
      • 성훈
        오버로딩을 이용한겁니다.

        위 "0으로 나누는 것은 허용되지 않습니다." 라는 내용을 출력하고 싶으면

        DivideException(String message){
        super(message);
        }

        을 사용하는것이고, 메시지출력없이 그냥

        if(this.right == 0){
        throw new DivideException();
        }

        이었으면

        DivideException(){
        super();
        }
        을 사용합니다
        대화보기
        • 저녁
          저도 생활코딩 강의를 통해 OOP 및 java를 공부하는 중이라 매 강의를 통해 알아가는 실력이지만 답글 달아봅니다. 설명 중에 부적절하거나 부족한 점이 있다면 지적해주세요.

          일단 super가 두 번 반복된다는 질문이 무엇을 물어보는 것인지 정확하겐 모르겠습니다.
          다만 DivideException() {} 과 DivideException(String message) {}는 둘 다 생성자라고 볼 수 있습니다.
          DivideException() {} 는 기본 생성자이며 DivideException(String message) {}는 파라메터로 문자열을 입력하였을 때 DivideException이란 클래스를 생성하기 위한 생성자인 것이죠.

          저는 java API를 따로 알아보진 않아서 잘 모르지만 기본 생성자와 문자열을 파라메터로 받는 생성자 둘다 DivideException이 상속받는 클래스인 Exception에 정의되어 있는 것 같습니다. 생성자 안에 super(), super(String message)로 쓰고 끝낸 걸 보면요.

          기본 생성자와 문자열을 파라메터로 받는 생성자 두 가지를 굳이 왜 만든 것이냐는 게 질문이라면
          저는 1) DivideException을 파라메터 없이 쓰는 경우와 문자열을 파라메터로 받아서 사용하는 경우 두 경우에 모두 쓰기 위함 이거나, 2) DivideException을 부모로 하는 또 다른 예외 클래스를 만들게 되는 경우를 대비하기 위함 이라고 생각하고 이해했습니다.

          해당 부분에 대한 강의는 '상속과 생성자'에서 유사한 내용을 다루고 있습니다.
          대화보기
          • 윤현준
            package org.opentutorials.javatutorials.exception;
            class DivideException extends Exception {
            DivideException(){
            super();
            }
            DivideException(String message){
            super(message);
            }
            }

            왜 super이 두번 반복되는지 생성자 강의를 한번 더 봤는데도 이해가 잘 안가네요 ㅠㅠ 설명 좀 부탁드려요
          • GoldPenguin
            감사합니다.
          • zugi
            완료.!
          • Seongho Kim
            덕분에 예외처리의 시야가 매우매우 넓어졌습니다. 친절하고 상세한 설명 깊이 감사드립니다(^^).
          • gomu92
            동기부여 덜 된다는말 공감합니다.. 공부하면서 멘탈 흔들렸네요ㅠㅠ다음에 다시 오겠습니다..
          • 지금까지 쭉 순항하다가 예외처리에서 멘탈이 살짝...
            안드로이드때문에 참고중인데 정말 큰 도움이 되고 있습니다. 감사합니다.
          • 2번째 3번째 코드에서
            throw가 try밖에 있어서 catch문에 접근이 안되는데 의도 하신건가요?
          • J_Project
            굿! 힘들었지만 잘 들었습니다.
          • 진격의숑숑
            감사합니다
          • 하파
            감사합니다. 고지가 멀지 않았네요. 끝까지 잘 듣겠습니다 ^^
          • 라떼
            어려워서 다음에 와서 또 봐야겠어요 ㅠ 감사합니다!
          • 김지
            마지막강의 잘 모르겠어요ㅠㅠ더봐야겠습니다 감사합니다
          • JustStudy
            들을수록 더욱 훌륭한 강의입니다,
            고맙습니다
          • 김트라슈
            감사합니다.
          • 코딩인가비
            갈수록 어렵지만 끝까지~
            고맙습니다
          • 오빠는다르다
            감사합니다!!!!!
          • Nick
            좋은 강의에 항상 고마움을 품고 늘 새겨 듣고 있습니다. 감사합니다.

            사실 자바는 에러가 발생하지 않토록 완벽하게 코딩을 한다고 해도
            try ..... catch ... 는 의무적으로 사용을 해야 되는 점에서 많은 다른언어와 좀더 차별 되는것 같아요

            좀 비슷한 C++ 도 예외처리를 코딩하던 안하던 전적으로 프로그래머의 책임인 반면
            자바는 checked인 부분에서는 예외처리없이는 컴파일조차 되지 않으니
            예외부분을 결코 가볍게 여길수 없는 이유중에 하나가 아닐까 생각합니다.

            3번정도 반복하다보니 흐르스름하게 잡혀오네요 ^^
          • 박첩구드
            어려워서 다음에 들어야겠어요 ㅠ
          • cocohodu
            좋은 강의 감사합니다
          • Ben Kim
            IDE에서 처리하는대로 해서 컴파일 에러만 없애는 식으로 가볍게 여겼는데 디테일한 의미를 알게 되어 좋았습니다.
            이고잉님 감사합니다.
          • 풍운도장
            어렵네요. 나중에 다시 방문해서 봐야겠어요.
          • Tony
            checked 예외는 반드시 예외처리를 해야 "하는 되는" 것이고, unchekced는 해도 되고 안 해도 되는 예외다.

            수정이 필요한 부분이라고 생각되어 댓글 남깁니다. 감사한 마음으로 강의 잘 듣고 있습니다.
          • 진화
            강의 잘들었어요. 설명을 잘해주셔서 이해가 잘되네요 감사합니다^^
          • jeyul
            checked와 unchecked 예외,, 강의 잘 들었습니다.

            checked 예외
            - RuntimeException을 제외한 Exception의 하위 클래스
            - 반드시 예외 처리를 해야 된다.
            - API 쪽에서 예외를 던졌을 때 API 사용자 쪽에서 예외 상황을 복구 할 수 있다면 checked 예외를 사용한다.

            unchecked 예외
            - RuntimeException의 하위 클래스
            - 예외 처리를 해도 되고 안 해도 된다.
            - 사용자가 API의 사용방법을 어겨서 발생하는 문제거나 예외 상황이 이미 발생한 시점에서 그냥 프로그램을 종료하는 것이 덜 위험 할 때 unchecked를 사용한다.
          • Sirhc
            나오던데요...

            System.out.println(e.left.);
            System.out.println(e.right);
            대화보기
            • hehypapa
              아 예외부분은 좀 어렵네요... 제가 집중력이 떨어져서 그런지...다시 봐야겠어요..ㅎㅎ
              강의 잘보고 있어요~
            • 도로시
              다형성부터 예외부분까지 아주 재미있네요 ^^

              한 가지 질문이 있는데요..
              마지막 영상에서 다룬 예제를 보면 (영상의 16분 즈음이고 텍스트에서는 예제가 약간 다릅니다)
              if(this.right == 0){
              throw new DivideException("0으로 나누는 것은 허용되지 않습니다.", this.left, this.right);
              }
              라고 넣는데 왜 e.getMessage를 하면 this.left 값과 this.right 값은 오류메시지로 안 나오고 문자열 부분만 나오나요?
            • Lewis6
              안녕하세요 ^^
              문의하신 내용이 (예외 강의 12/12) 중 9분 30초 ~ 10분 20초 내용에서 설명이 되는 것 같네요.

              "Exception 클래스를 상속받아 만들어진 super(message) 생성자
              즉, 인자값(String message)이 있는 생성자를 만들 경우 ,
              자바에서는 기본 생성자를 만들어주지 않기 때문에
              그 위에 super() 라는 기본생성자를 먼저 만들어준다... "

              는 설명이 있습니다.

              생성자 부분에서 다루어진 내용이네요. ^^
              대화보기
              • 생활코딩인
                안녕하세요. 강의 정말 잘 듣고 있습니다. 감사드려요. 한 가지 궁금한 게 있어서 그러는데요,
                위의 예제에서, 예외를 처리하는 입장에서요.. 예외를 처음 발생시킬 때 DivideException(String message, int left, int right)로 생성된 줄 알고
                자기한테 전달된 예외 클래스 e의 e.left와 e.right를 보니 각각 0, 0이라서 0을 0으로 나눴나보다 생각할 수 있을텐데요,
                실제로 코딩한 쪽에서는 DivideException(String message)만 사용해서 left와 right의 값이 예외클래스에 전달되지 않은 경우에는
                예외처리하는 쪽에서 이걸 구별할 수 있는 방법이 없을까요? 실제로는 10을 0으로 나눴는데 처리하는 입장에서는 둘다 0으로 보이는 사태가... 생길 수 있지 않을까 걱정이 되어서요
              • 워너비개발자
                예외에 대한 내용이 이렇게나 많았을 줄은 몰랐네요.; 정말 많이 배우고 갑니다. 그런데 한가지 궁금한게 있는데요 마지막 예제에서
                DivideException(){
                super();
                DivideException(String message){ <- 이부분은 위에서 생성자를 정의하고 밑에서 그 필요한,
                super(message); 내용들을 추가했는데 왜 중복되서 사용되는건가요?
                }
                DivideException(String message, int left , int right){
                super(message);
                this.left = left;
                this.right = right;
                }
              • 좋은 정보 감사합니다. findbugs 돌리다 저도 모르는 이슈가 나와서 검색하다 여기까지 찾아왔네요~
              • 응딩이
                예외의 선조 - Throwable 에서 마지막줄오타났네영 히히
              버전 관리
              egoing
              현재 버전
              선택 버전
              graphittie 자세히 보기