๐Ÿ“– Exception์— ๋Œ€ํ•˜์—ฌ


์˜ค๋Š˜ ์ˆ˜์—… ์‹œ๊ฐ„์— ์ž๋ฐ”์˜ Exception์— ๋Œ€ํ•ด ๋ฐฐ์› ๋‹ค.
์ˆ˜์—…์„ ๋“ฃ๊ณ  ๋“ค์€ ๋‚ด์šฉ์„ ์ž๋ฐ”์˜ ์ •์„์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•จ๊ป˜ ๋ณด๋ฉด์„œ ์ •๋ฆฌ โœ๏ธ

ํ”„๋กœ๊ทธ๋žจ ์˜ค๋ฅ˜ ์ข…๋ฅ˜

  • ์ปดํŒŒ์ผ ์—๋Ÿฌ - ์ปดํŒŒ์ผ ์‹œ์— ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ
  • ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ - ์‹คํ–‰ ์‹œ์— ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ
  • ๋…ผ๋ฆฌ์  ์—๋Ÿฌ - ์‹คํ–‰์€ ๋˜์ง€๋งŒ, ์˜๋„์™€ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ

ํ”„๋กœ๊ทธ๋žจ์—์„œ ์‹คํ–‰ ๋„์ค‘ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ณ ๋ คํ•ด ์ด์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ๋Œ€๋น„๊ฐ€ ํ•„์š”ํ•˜๋‹ค!

Error์™€ Exception์˜ ์ฐจ์ด?

Error

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”๋ฐ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•œ๋‹ค.
ex) ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์ด๋‚˜ ์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋“ฑ

๊ฐœ๋ฐœ์ž๊ฐ€ Error๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ผ์€ ๊ฑฐ์˜ ์—†๋‹ค๊ณ  ํ•œ๋‹ค.

Exception

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ƒ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•œ๋‹ค.
๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์ˆ˜์Šต์ด ๊ฐ€๋Šฅํ•˜์—ฌ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ด์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์™ธ ํด๋ž˜์Šค ๊ณ„์ธต ๊ตฌ์กฐ

๋ชจ๋‘ Throwable์„ ์ƒ์†ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ Error์™€ Exception์ด ๋ฐœ์ƒํ•œ๋‹ค.
์—ฌ๊ธฐ์„œ ๋ชจ๋“  ์˜ˆ์™ธ์˜ ์กฐ์ƒ์€ Exception ํด๋ž˜์Šค์ด๋‹ค.

๋˜ ์˜ˆ์™ธ ํด๋ž˜์Šค๋“ค์€ ๋‘ ๊ฐœ์˜ ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋‰˜์–ด ์งˆ ์ˆ˜ ์žˆ๋‹ค.

  • RuntimeException ํด๋ž˜์Šค์™€ ๊ทธ ์ž์† ํด๋ž˜์Šค๋“ค
  • Exception ํด๋ž˜์Šค์™€ ๊ทธ ์ž์† ํด๋ž˜์Šค๋“ค

์ด ๊ธ€์—์„œ๋Š” RuntimeException ํด๋ž˜์Šค์™€ ๊ทธ ์ž์† ํด๋ž˜์Šค๋“ค์„ Checked Exception์ด๋ผ ํ•˜๊ณ ,
Exception ํด๋ž˜์Šค์™€ ๊ทธ ์ž์† ํด๋ž˜์Šค๋“ค์„ Unchecked Exception์ด๋ผ๊ณ  ํ•˜๊ฒ ๋‹ค.

Checked Exception

import lotto.view.ErrorView;

public class CustomException extends Exception {
    public CustomException() {
        ErrorView.printErrorMessage();
    }
}

โ€ฆ


public class Application {
    public static void main(String[] args) throws CustomException {
        LottoNumber lottoNumber = LottoNumber.from(1);
    }
}

Exception์„ ์ƒ์†๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ปดํŒŒ์ผ ์‹œ์ ์— Exception์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
๋งŒ์•ฝ ์ปดํŒŒ์ผ ์‹œ์ ์— Exception์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ(try/catch)๋ฅผ ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
Exception์ด ๋ฐœ์ƒํ•˜๋Š” ๋ฉ”์†Œ๋“œ์—์„œ throws ์˜ˆ์•ฝ์–ด๋ฅผ ํ™œ์šฉํ•ด
Exception์„ ํ˜ธ์ถœ ๋ฉ”์†Œ๋“œ์— ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.

์ƒ์œ„ ๋ฉ”์„œ๋“œ๋กœ throw๋ฅผ ๋˜์ง€๋Š” ํ–‰์œ„๋Š” ์ƒ์œ„ ๋ฉ”์„œ๋“œ๋“ค์˜ ์ฑ…์ž„์ด ๊ทธ๋งŒํผ ์ฆ๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์—,
๊ทธ๋ฆฌ ์ข‹์€ ๋ฐฉ๋ฒ• ๊ฐ™์ง€๋Š” ์•Š๋‹ค.

Unchecked Exception

public class IllegalLottoNumberException extends IllegalArgumentException {
    public IllegalLottoNumberException() {
        ErrorView.printIllegalLottoNumberMessage();
    }
}

โ€ฆ

public class LottoNumber implements Comparable<LottoNumber> {
    public static final int MIN_LOTTO_NUMBER = 1;
    public static final int MAX_LOTTO_NUMBER = 45;
    private static final Pattern NUMBER_PATTERN = Pattern.compile("^[0-9]*$");

    private final int value;

    public LottoNumber(String number) {
        validateLottoNumber(number);
        this.value = Integer.parseInt(number);
    }

    private void validateLottoNumber(String number) {
        if (isBlank(number) || isInvalidNumberFormat(number) || isInvalidLottoNumberRange(number)) {
            throw new IllegalLottoNumberException();
        }
    }

Runtime Time Exception ์ด๋ผ๊ณ  ํ•œ๋‹ค.
์ปดํŒŒ์ผ ์‹œ์ ์— Exception์ด ๋ฐœ์ƒํ•  ๊ฒƒ์ธ์ง€์˜ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•  ์ˆ˜ ์—†๋‹ค.
Exception์ด ๋ฐœ์ƒํ•˜๋Š” ๋ฉ”์†Œ๋“œ์—์„œ throws ์˜ˆ์•ฝ์–ด๋ฅผ ํ™œ์šฉํ•ด Exception์„ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์ง€๋งŒ, ์ฒ˜๋ฆฌํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.

Checked Exception VS Unchecked Exception

๊ตฌ๋ถ„ Checked Exception Unchecked Exception
ํ™•์ธ ์‹œ์  ์ปดํŒŒ์ผํƒ€์ž„ ๋Ÿฐํƒ€์ž„
์ฒ˜๋ฆฌ ๋ฐ˜๋“œ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค. throws๋ฅผ ํ†ตํ•ด ๊ทธ๋ƒฅ ๋˜์ ธ๋„, ์ฒ˜๋ฆฌํ•ด๋„ ์ƒ๊ด€ ์—†๋‹ค.
๋Œ€ํ‘œ ์˜ˆ์™ธ IOException, SQLException IllegalArgumentException, NullPointEception

๋„ˆ๋ฌด ์น˜๋ช…์ ์ด๋ฉด Checked ์“ฐ๊ณ ,
๊ตณ์ด ๊ฒฝ๊ณ ๊ฐ€ ํ•„์š”์—†๊ณ , ์„œ๋น„์Šค ์ฝ”๋“œ๋ฅผ ๋งŒ๋“œ๋Š” ์ž…์žฅ์ด๋ผ๋ฉด ์ตœ์ƒ๋‹จ์—์„œ
์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋ง ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ Unchecked๋ฅผ ์“ฐ๋Š”๊ฒŒ ์ข‹๋‹ค.

์ฐธ๊ณ ๋กœ ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” Checked Exception์€ ์ฝ”๋“œ๋งŒ ๋Š˜์–ด๋‚  ๋ฟ์ด๋ผ ์ƒ๊ฐ(?)ํ•ด์„œ
์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ด์œ ๋กœโ€ฆ Checked Exception์ด ์—†๋‹ค๊ณ  ํ•œ๋‹ค.
๋˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ ์ž…์žฅ์—์„œ ๋ฉ”์ธ๊ณผ ๊ฐ™์€ ์ค‘์•™์—์„œ ํ•ธ๋“ค๋งํ•˜๋Š” ๋…€์„์„ ๋งŒ๋“ค์–ด ๊ด€๋ฆฌํ•˜๋Š”๋ฐ,
๊ตณ์ด ์šฐ๋ฆฌ๊ฐ€ Checked Exception์„ ์ œ๊ณตํ•  ํ•„์š”๊ฐ€ ์žˆ๋ƒ๋Š” ๋ง์ด๋‹ค.

์ˆ˜์—…์‹œ๊ฐ„์— ๋‹ค์–‘ํ•œ ๋ง๋“ค๋กœ ๋‘˜์„ ๊ตฌ๋ถ„์ง€์–ด ๋ณด์•˜๋Š”๋ฐ,
**Checked Exception๋Š” **

  • ๋‚ด๋ถ€ ๊ตฌํ˜„์ด ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๊ณ  ์‹ถ์–ด!
  • ๋‚ด๊ฐ€ ์ง‘ ์ˆ˜๋ฆฌํ• ๊ฑด๋ฐ ์† ๋‹ค์น ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ๊นŒ ๊ตฌ๊ธ‰์ฐจ ๋ฏธ๋ฆฌ ๋ถˆ๋Ÿฌ!
  • ๋„ˆ ์ง„์งœ ์กฐ์‹ฌํ•ด์•ผํ•ด!

**Unchecked Exception๋Š” **

  • ๋‚ด๋ถ€์—์„œ ์˜ˆ์™ธ์— ๋Œ€ํ•œ ๋ฐฉ์–ด๊ฐ€ ์žˆ๋Š”๋ฐ ํด๋ผ์ด์–ธํŠธํ•œํ…Œ ๊ณต๊ฐœ๋Š” ์•ˆํ• ๊ฑฐ์•ผ, ๋Œ€์‹  ๊ฐ’์„ ์ž˜ ๋„ฃ์–ด์ฃผ๋ฉด ์ข‹๊ฒ ์–ด.
  • ๋‚ด๊ฐ€ ์ง‘ ์ˆ˜๋ฆฌํ• ๊ฑด๋ฐ ์•„๋ƒ ๋‹ค์น˜์ง€ ์•Š๊ณ  ์ž˜ ํ•  ์ˆ˜ ์žˆ์–ด!
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ž…๋ ฅํ•  ๊ฐ’์„ ์ž˜ ์•Œ๊ณ  ์žˆ๊ฒ ์ง€ ~

์ด๋Ÿฐ ๋Š๋‚Œ์œผ๋กœ ์ด์•ผ๊ธฐ๊ฐ€ ๋‚˜์™”๋‹ค.
Checked์ธ์ง€ Unchecked์ธ์ง€๋Š” ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์–ผ๋งˆ๋‚˜ ์ฑ…์ž„์„ ๋– ๋„˜๊ธฐ๋Š๋ƒ์— ๋Œ€ํ•œ ๊ด€์ ์œผ๋กœ ๋ด๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

์˜ˆ์™ธ ์ฒ˜๋ฆฌ - try-catch๋ฌธ

try {
    // ์˜ˆ์™ธ ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ ์žˆ๋Š” ๋ฌธ์žฅ๋“ค
} catch (Exception1 e1){
    // Exception1์ด ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ, ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฌธ์žฅ
} catch(Exception2 e2) {
    // Exception2๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ, ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฌธ์žฅ
}

์ด๋ ‡๊ฒŒ ํ•˜๋‚˜์˜ try ๋ธ”๋Ÿญ ๋‹ค์Œ์—๋Š” ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก
ํ•˜๋‚˜ ์ด์ƒ์˜ catch ๋ธ”๋Ÿญ์ด ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

ํ๋ฆ„

try ๋ธ”๋Ÿญ์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ์œ„์น˜ ์ดํ›„์— ์žˆ๋Š”
try ๋ธ”๋Ÿญ์˜ ๋ฌธ์žฅ๋“ค์€ ์ˆ˜ํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
๋•Œ๋ฌธ์— try ๋ธ”๋Ÿญ์— ํฌํ•จ์‹œํ‚ฌ ์ฝ”๋“œ์˜ ๋ฒ”์œ„๋ฅผ ์ž˜ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค.

์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ์— ํ•ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค.
try๋ธ”๋Ÿญ์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ๋˜๊ณ , ์ฒซ catch ๋ฌธ๋ถ€ํ„ฐ ์ฐจ๋ก€๋Œ€๋กœ catch ๋ธ”๋Ÿญ์˜
๊ด„ํ˜ธ ๋‚ด ์„ ์–ธ๋œ ์ฐธ์กฐ๋ณ€์ˆ˜์˜ ์ข…๋ฅ˜์™€ ์ƒ์„ฑ๋œ ์˜ˆ์™ธ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์— instanceof์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•ด ๊ฒ€์‚ฌํ•œ๋‹ค.
๊ฒ€์‚ฌํ•œ ๊ฒฐ๊ณผ๊ฐ€ true์ธ ๋ธ”๋Ÿญ์„ ๋งŒ๋‚  ๋•Œ ๊นŒ์ง€ ๊ณ„์† ๊ฒ€์‚ฌํ•œ๋‹ค.

try์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ์˜ ์ข…๋ฅ˜์™€ ์ผ์น˜ํ•˜๋Š” ๋‹จ ํ•˜๋‚˜์˜ catch ๋ธ”๋Ÿญ๋งŒ ์ˆ˜ํ–‰๋œ๋‹ค.

public class LottoNumber {
    private final int number;

    private LottoNumber(int number) {
        this.number = number;
    }

    public static LottoNumber from(final int number) throws CustomException {
        throw new CustomException();
    }
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด LottoNumber ๊ฐ์ฒด๋ฅผ from()์œผ๋กœ ์ƒ์„ฑํ–ˆ์„ ๋•Œ
Exception์„ ์ƒ์†๋ฐ›๊ณ  ์žˆ๋Š” CustomException์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค๊ณ  ํ•ด๋ณด์ž.

์ธํ…”๋ฆฌ์ œ์ด์—์„œ๋„ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด CustomException์˜ ์ƒ์œ„ ํด๋ž˜์Šค์ธ
Exception์„ ๋ฏธ๋ฆฌ catchํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•˜์œ„ catch์—์„œ
CustomException๋ฅผ ์žก๋Š” ๊ฒƒ์€ ์†Œ์šฉ์ด ์—†๋‹ค.

๋ชจ๋“  ์˜ˆ์™ธ ํด๋ž˜์Šค๋Š” Exception ํด๋ž˜์Šค์˜ ์ž์†์ด๋ฏ€๋กœ,
Exception ํด๋ž˜์Šค ํƒ€์ž…์˜ ์ฐธ์กฐ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด ํ•ด๋‹น ๋ธ”๋Ÿญ์—์„œ ์–ด๋–ค ์˜ˆ์™ธ๋˜์ง€ ์ฒ˜๋ฆฌ๋œ๋‹ค.

๋˜ ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œ์ผœ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

๋ฉ€ํ‹ฐ catch ๋ธ”๋Ÿญ
JDK1.7๋ถ€ํ„ฐ catch ๋ธ”๋Ÿญ์„ |์„ ์ด์šฉํ•ด ํ•˜๋‚˜์˜ catch ์ ๋Ÿญ์œผ๋กœ ํ•ฉ์น  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๋ถ€๋ชจ ์ž์‹ ๊ด€๊ณ„๊ฐ€ ์žˆ๋‹ค๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ค‘์ฒฉ๋œ try-catch

ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ ์•ˆ์— ์—ฌ๋Ÿฌ๊ฐœ์˜ try-catch๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ,
์ค‘์ฒฉ์œผ๋กœ๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
ํ•˜์ง€๋งŒ catch๋ธ”๋Ÿญ ๊ด„ํ˜ธ ๋‚ด ์ฐธ์กฐ ๋ณ€์ˆ˜๋Š” catch ๋ธ”๋Ÿญ ๋‚ด์—์„œ ์œ ํšจํ•œ๋ฐ,
์œ„์˜ ์˜ˆ์ œ์—์„œ๋Š” e์˜ ์ฐธ์กฐ๋ณ€์ˆ˜์˜ ์˜์—ญ์ด ์„œ๋กœ ๊ฒน์น˜๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.

Custom Exception

๊ธฐ์กด์— ์ •์˜๋œ ์˜ˆ์™ธ ํด๋ž˜์Šค ์™ธ์— ํ•„์š”์— ๋”ฐ๋ผ ์‚ฌ์šฉ์ž ์ •์˜ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

class MyException extends Exception {
    MyException(String msg) {
        super(msg); 
    }
}

์ƒ์„ฑ์‹œ string์„ ์ธ์ž๋กœ ๋ฐ›์•„์„œ ๋ฉ”์‹œ์ง€๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.