[바로실습] 생활코딩 - 자바(JAVA)
    • 01
      언어 소개
    • 언어 소개
    • 02
      숫자와 문자
    • 숫자
      문자와 문자열
    • 03
      변수
    • 변수의 선언과 할당
      정수와 실수
      문자열
      변수의 효용
    • 04
      주석과 세미콜론
    • 주석과 세미콜론
      주석과 세미콜론 - Quiz
    • 05
      데이터 타입
    • 데이터의 크기
      데이터 타입의 종류
    • 06
      상수의 데이터 타입
    • 상수의 데이터 타입
    • 07
      형 변환
    • 형 변환
      명시적 형 변환
    • 08
      연산자
    • 산술 연산자
      형변환
      단항 연산자
      연산의 우선순위
    • 09
      비교와 Boolean
    • 비교와 Boolean
    • 10
      조건문
    • if
      else
      변수와 비교연산자 그리고 조건문
      조건문의 중첩
      switch 문
    • 11
      논리 연산자
    • AND ( && )
      OR ( || )
      NOT ( ! )
    • 12
      반복문
    • while
      for
      반복문이 없다면
      반복문의 제어
      반복문의 중첩
    • 13
      배열
    • 배열
      배열의 개념
      제어
      배열의 사용
      for-each
      오류
    • 14
      메소드
    • 메소드
      메소드의 정의와 호출
      메소드가 없다면
      입력값
      return
    • 15
      입력과 출력
    • 입력과 출력
      앱이 시작할 때 데이터를 입력
      앱이 실행중에 데이터를 입력
      여러 형태의 입출력
    • 16
      객체 지향 프로그래밍
    • 객체 지향 프로그래밍
      추상화
      부품화
    • 17
      클래스와 인스턴스 그리고 객체
    • 클래스와 인스턴스 이전의 프로그래밍
      객체화1
      객체화2
      객체화3
    • 18
      클래스 맴버와 인스턴스 맴버
    • 맴버
      클래스 변수
      클래스 메소드
      맴버타입의 비교
    • 19
      유효범위
    • 유효범위
      전역변수와 지역변수
      다양한 유효범위들
      인스턴스의 유효범위
    • 20
      초기화와 생성자
    • 초기화와 생성자
    • 21
      상속
    • 상속의 개념
      코드로 알아보는 상속
      다양한 종류의 상속
    • 22
      상속과 생성자
    • 기본 생성자
      super
    • 23
      overriding
    • overriding1
      overriding2
    • 24
      overloading
    • overloading1
      overloading2
    • 25
      클래스 패스
    • 컴파일과 클래스
      클래스의 경로
      환경변수
    • 26
      패키지
    • 패키지의 개념
      패키지의 사용
      손 컴파일
      중복의 회피
    • 27
      API와 API 문서 보는 법
    • API와 API 문서1
      API와 API 문서2
    • 28
      접근 제어자
    • 접근 제어자
      자유와 규제
      접근 제어자를 사용하는 이유
      세밀한 제어
      클래스의 접근 제어자
    • 29
      abstract
    • 문법
      추상클래스를 사용하는 이유
      디자인 패턴
    • 30
      final
    • final
    • 31
      인터페이스
    • 문법과 개념
      사용하는 이유
      규칙들
    • 32
      다형성
    • 메소드와 다형성
      클래스와 다형성1
      클래스와 다형성2
      실전 예제
      인터페이스와 다형성1
      인터페이스와 다형성2
    • 33
      예외1 - 문법
    • 성공과 실패
      예외란?
      뒷수습의 방법
      다양한 예외들
      finally
    • 34
      예외2 - 예외 던지기
    • 예외의 강제
      throw와 throws
      책임의 전가 throws
    • 35
      예외3 - 만들기
    • 예외 만들기
      예외의 여러가지 상황들
      예외의 선조 - Throwable
      나만의 예외 만들기
    • 36
      Object 클래스
    • 상속
      toString
      equals
      finalize
      clone
    • 37
      상수와 enum
    • 상수에 대한 복습
      enum의 배경
      enum의 문법
      enum과 생성자
    • 38
      참조
    • 복제
      참조
      참조와 복제
      메소드와 참조
    • 39
      제네릭
    • 제네릭의 사용
      제네릭을 사용하는 이유
      제네릭의 특성
      제네릭의 생략
      제네릭의 제한
    • 40
      Collections Framework
    • ArrayList의 사용법
      전체적인 구성
      List와 Set의 차이점
      Set
      Map
      정렬
    예외 만들기
    배우기
    35 예외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산술적인 연산에 오류가 있을 때

    실습 내용

    실행결과

    Exception in thread "main" java.lang.IllegalArgumentException:    0   .
        at org.opentutorials.javatutorials.exception.Calculator.setOprands(CalculatorDemo.java:7)
        at org.opentutorials.javatutorials.exception.CalculatorDemo.main(CalculatorDemo.java:30)


    질문하기