프로그래밍 언어들

예외 3 - 만들기

토픽 프로그래밍 언어들 > Java

소비자에서 생산자로

지금까지 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. 교사H
    23.02.24 완강했지만 이해 안 감
  2. coster97
    재미따
  3. wwwqiqi
    기계적으로 트라이캐치문만 썼는데 checked, unchecked의 개념과 직접 예외를 만들어서 사용도 해보니
    훨씬 깊이가 깊어진것 같아요. 이제 어떻게 쓰느냐 좀 더 생각해 볼 수 있겠네요ㅎㅎ
    좋은 강의 감사합니다. 완료
  4. givendragon
    220906
    12 13 re
  5. Raye
    (https://docs.oracle.com......tml)
    url 참고했습니다!

    정확한지는 저도 공부하면서 배워가겠습니다!
    찾아보니 Exception 클래스는 암묵적 클래스 같아요.
    오라클에서 확인해보면 이런 느낌인 거 같아요.

    class Exception{

    Exception();
    Exception(String message);
    Exception(String message, Throwable cause);
    Exception(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
    Exception(Throwable cause);

    }

    예제 안에서 class DivideException는 Exception 클래스를 상속받고 있고 Exception 클래스의 Exception(), Exception(String message) 메소드를 오버라이딩하고 있네요옹
    대화보기
    • PassionOfStudy
      복습 5일차!
    • PassionOfStudy
      예외3 - 만들기!
    • 코드파괴자
      22.05.06 Form Ride. Throwable //
    • 모찌말랑카우
      22.03.02 완료
    • aesop0207
      22.02.19. Fri
    • 행달
      22.02.06 완료!
    • 유학생
      킵고잉하면서 듣고 있는데, 너무 어렵네요. 우선 그냥 넘어간 후 다시 돌려보는 방향으로 해야겠어요
    • 초코라비
      질문이요..!
      'super' 라는게 상위 클래스에 있는 것을 중복 없이 받을려고 쓰는 것 아닌가요? 근데 "class DivideException extends Exception" 여기에서 DivideException 클래스가 Exception 클래스를 상속하는건데 Exception이라는 클래스는 따로 클래스를 만들어서 정의하지도 않고있는 상태인데 super를 왜 쓸 수 있는건가요?
    • 드림보이
      2021.12.23. 예외 3 - 만들기 파트 수강완료
    • syh712
      2021-12-10
      <예외 3 - 만들기>
      1. 소비자에서 생산자로
      - 예외 사용해야 할 상황
      IllegalArgumentException 매개변수가 의도하지 않은 상황을 유발시킬 때
      IllegalStateException 메소드를 호출하기 위한 상태가 아닐 때
      NullPointerException 매개 변수 값이 null 일 때
      IndexOutOfBoundsException 인덱스 매개 변수 값이 범위를 벗어날 때
      ArithmeticException 산술적인 연산에 오류가 있을 때\

      2. 예외의 여러가지 상황들
      IOException은 예외처리를 강제하고 있지만 ArithmeticException은 그렇지 않다 점. 왜그럴까?

      3. 예외의 선조 - Throwable
      - 클래스 Throwable은 범 예외 클래스들의 공통된 조상
      - Error는 여러분의 애플리케이션의 문제가 아니라 그 애플리케이션이 동작하는 가상머신에 문제가 생겼을 때 발생하는 예외
      - checked 예외는 반드시 예외처리를 해야 하는 되는 것이고, unchekced는 해도 되고 안 해도 되는 예외
      - IOException(<RunTimeException>에 속함)은 checked; ArithmeticException(<Exception>에 속함)은 unchekced; Error도 unchecked

      4. 나만의 예외 만들기
      - API 사용자 쪽에서 예외 상황을 복구 할 수 있다면 checked 예외를 사용한다
      - API의 사용방법을 어겨서 발생하는 문제거나 예외 상황이 이미 발생한 시점에서 그냥 프로그램을 종료하는 것이 덜 위험 할 때 unchecked를 사용한다.
    • 네제가해냈습니다
      예외 1,2를 이해하고 실전에서도 사용하는 상황 후에 예외3를 보는게 낫겠습니다.
    • H4PPY
      1110
    • IaaS
      2021-11-03 수강완료

      이번 예외수업에서 기분찝찝하네요.

      머리로는 이해했는데 실전에서 예외처리를 어떻게 해야할지 앞으로 깜깜하네요.
    • super1Nova
      210908
    • 코딩쟁이
      super 두번 호출하는거에 대해서,

      클래스에서 기본 생성자(인자 없는) 외 전달 인자가 있는 생성자를 정의할 경우, 기본 생성자는 생성되지 않으므로 추가로 직접 정의가 필요하다가 핵심인 듯 합니다.

      1) RuntimeException에는 아마 기본 / string 생성자가 둘 다 존재할 것이다. super로 call 되는 것을 확인하자.

      2) DivdeException에 아무것도 정의하지 않을 경우(생성자 아무것도 정의하지 않고 상속만 할 경우), 자바는 자동으로 기본 생성자를 생성할 것이다. 이는 인자가 없는 것을 생성하는 기본 생성자가 자동으로 생성되는 것으로 보인다. 따라서 throw new DivideException( )처럼 아무 인자가 없을 경우에는 에러가 없다.

      3) throw new DivideException에 string이 전달될 경우, 해당 생성자가 없으므로 에러가 발생한다.

      따라서 DivideException(String message) { super ~) 를 작성해준다.

      4) 이 경우, 인자가 있는 생성자가 DivideException의 기본 생성자가 된다. 사용자가 정의했으므로 자바는 인자 없는 생성자를 만들어 주지 않는다.

      5) 따라서 throw new DivideException( ) 처럼 인자 없이 호출되는 생성자는 에러가 난다. 그러므로 이것도 정의해줘야 한다.

      6) 결론적으로, 인자 있는 생성자와 없는 생성자를 둘 다 받기 위해서 각각 정의가 필요하다.
    • cuole
      댓글을 보고 super()를 두번쓰는 것에 대해서 이 예제 말고 자바 책에 있는 다른 예제를 통해 요리조리 돌려봤는데
      DivideException(){ super();}
      DivideException(){}
      둘 중 아무거나 써도 똑같은 결론이 나옵니다.

      super()를 생략해도 컴파일러가 알아서 호출해주는데 예제에서는 그냥 명시해준 것 같네요.
    • 김루퍼
      이런걸 만든 사람들은 정말 천재라는 생각밖에 안든다..
      머리터질거같아~
    • 김요한
      2020.08.05
      예외에 대한 전반적인 강의를 이해하지 못해서 오늘은 힘이 드네요...
      일단 넘어가고 다시 수강하겠습니다..
      멘탈이 많이 흔들리네요...
    • 김승민
      2020-04-28
      감사합니다~
    • Jaden
      동영상의 10분 10초부터 다시한번 천천히 들어보시면 이해가 되실거라고 생각됩니다. 그래도 이해가 되시지 않는다면 상속과 생성자 영상을 다시 들어보세요
      대화보기
      • 사실

        DivideException(){
        super();
        }

        이 코드는 필요 없다고 생각합니다.

        있어도 그만 없어도 그만같네요.
        대화보기
        • 이무송
          감사합니다!
        • 허공
          감사합니다!
        • 홍주호
          20190928 완료
        • silver94
          잘봤습니다!!
        • doevery
          수강완료
        • 소월
          throw new DivideException("0으로 나눌 수 없습니다.", this.left, this.right);
          에서 this.left는 class Calculator의 this.left랑 똑같은건가요? this.xx면 모든 클래스에서 같은 값인가요?
        • 라또마니
          가장 어려운 강의 였던거 같습니다. 다시 한번 들어야 할 듯 싶어요
        • ㅁㄴㄹㅇ
          super로 기본생성자는 왜만드는건지 이해가 안되서 알수있을까요
        • 칼립소
          2차 정주행 완료
        • Daydream
          좀 어려운말인것 같네요
          exception 으로 처리해도되지만 각 자세한 예외처리가 불가하고
          예외를 몽땅 간단하게 처리하려면 exception 으로 그냥 넘기기로 에러를 숨김.

          20181028 좋은강의 감사합니다.
        • 좀 개소리같네요,,
          대화보기
          • 전하연
            감사합니다
            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
                  감사합니다.