Java/Java 문법

Java 문법 9 (오류 및 예외)

열심히 해 2024. 9. 9. 21:11
  • 오류(Error)는 일반적으로 회복이 불가능한 문제입니다.
    • 이는 시스템 레벨에서, 또는 주로 환경적인 이유로 발생합니다.
    • 코드의 문제로 발생하는 경우도 있지만, 일단 발생하는 경우 일반적으로 회복이 불가능합니다.
    • 에러가 발생한 경우 우리는 어떠한 에러로 프로그램이 종료되었는지를 확인하고 대응합니다.
  • 예외(Exception)는 일반적으로 회복이 가능한 문제입니다.
    • 회복이 가능하다는 전제는 우리가 “그 예외가 발생할 수 있다는 것을 인지하고, 대응했을 것입니다”.
    • 현실적으로 코드 레벨에서 할 수 있는 문제 상황에 대한 대응은 “예외 처리”에 속합니다.

코드 실행 관점에서 예외의 종류

  • 컴파일 에러(예외) 
    • .java 파일을 .class 파일로 컴파일할 때 발생하는 에러
    • 대부분 여러분이 자바 프로그래밍 언어의 규칙을 지키지 않았기 때문에 발생합니다.
    • 예를 들어 있지 않은 클래스를 호출한다거나, 접근이 불가능한 프로퍼티(속성)나 메소드에 접근한다거나 하는 경우에 발생합니다.
    • 컴파일 에러가 발생하는 경우 해결 방법은 문법에 맞게 다시 작성하는 것입니다.
  • 런타임 에러(예외)
    • 우리가 주로 다루게 될 에러(예외)입니다.
    • 문법적인 오류는 아니라서, 컴파일은 잘 되었지만 “프로그램”이 실행 도중 맞닥뜨리게 되는 예외입니다.

 

예외 처리 관점에서 예외의 종류

  • 확인된 예외 (Checked Exception)
    • 컴파일 시점에 확인하는 예외입니다.
    • 반드시 예외 처리를 해줘야 하는 예외입니다.
     * 컴파일 시점에 확인하는 예외라는 문구 때문에, 컴파일 에러와 헷갈리 시면 안됩니다. 우리가 이미 특정한 문제를 인지하고 있어서, 해당 예외를 정의해두었고, 정의해두었기 때문에 컴파일 하는 동안 이 예외에 대한 예외 처리를 했는지 확인(Check) 할 수 있는 예외입니다.
  • 즉 Checked Exception에 대한 예외 처리를 하지 않으면 컴파일 에러가 발생합니다.


  • 미확인된 예외 (Unchecked Exception)
    • 런타임 시점에 확인되는 예외입니다.
    • 예외 처리가 반드시 필요하지 않은 예외입니다.

`1. 우리가 예외를 어떻게 정의하고, 2. 예외가 발생할 수 있음을 알리고, 3. 사용자는 예외가 발생할 수 있음을 알고 예외를 핸들링하는지`의 흐름이 중요하다. // 키워드 : try, catch, finally, thorow


더보기
  • 예외 정의하기 : 예외 클래스를 만든다.
package week04.sample01;

// 예외 클래스를 만들어서 예외를 정의 !! 자식클래스 extends 부모클래스
public class OurBadException extends Exception {
    OurBadException () {
        super("위험한 행동에는 예외 처리가 필요함");

    }
}

 

  • 메서드에서 예외가 발생할 수 있음을 알리기 -> 예외가 발생할 수 있는 로직에 어떠한 플레그를 달아둔다.
package week04.sample01;

public class OutClass {
    private final boolean just = true;

    // throws : 던지다 ( 예외를 던지다, 발생시키다)
    public void thisMethodIsDangerous() throws OurBadException {   // throws OurBadException 을 통해 이 메서드에 예외가 있을 수 있음을 알리기.
        System.out.println("예외 발생");
        if (just) {
            throw new OurBadException(); //

        }
    }
}

 

 

  • 예외 핸들링
package week04.sample01;

public class StudyException {
    public static void main(String[] args) {
        OutClass ourClass = new OutClass();

//        ourClass.thisMethodIsDangerous(); // 위험하다고 알려진 메서드는 호출 불가
//        try ~ catch ~ finally 구문을 통해서 위험하다고 알려진 메서드를 호출할 수 있음.
//        일단 try ~ 예외가 발생하면 catch ~ (예외가 있든 없든) 이 로직은 finally 진행시켜

        try { // 일단 실행
            ourClass.thisMethodIsDangerous();
        } catch (OurBadException e) { // ()안에 있는 놈이 예외다. 그때 메세지 출력
            System.out.println(e.getMessage());
        } finally { // 무조건 실행됨
            System.out.println("무조건 무조건이야~");
        }
    }
}
// 예외 발생
// 위험한 행동에는 예외 처리가 필요함
// 무조건 무조건이야~

 

  • 문제 상황(오류, 예외) 관련 클래스 분류

- 시작은 모든 객체의 원형인 `Object` 클래스에서 시작합니다.
- '문제 상황'을 뜻하는 Throwable 클래스가 Object 클래스를 상속합니다.
- Throwable 클래스의 자식으로 앞서 배운 오류(Error)와 예외(Exception) 클래스가 있습니다.
- 오류(Error) 클래스의 자식으로  IOError 클래스 등이 있습니다.

- 예외(Exception) 클래스의 자식으로 IOException 클래스, RuntimeException 클래스가 있습니다.

- RuntimeException 클래스의 자식으로 NullPointException, ArrayIndexOutOfBoundsException, NumberFormatException이 있습니다.

 

 

 

Java 에서 제공하는 예외 구현체

 

출처 : https://programming.guide/java/list-of-java-exceptions.html 

 

더보기
java.io
        IOException
        CharConversionException
        EOFException
        FileNotFoundException
        InterruptedIOException
        ObjectStreamException
        InvalidClassException
        InvalidObjectException
        NotActiveException
        NotSerializableException
        OptionalDataException
        StreamCorruptedException
        WriteAbortedException
        SyncFailedException
        UnsupportedEncodingException
        UTFDataFormatException
        UncheckedIOException

java.lang

        ReflectiveOperationException
        ClassNotFoundException
        InstantiationException
        IllegalAccessException
        InvocationTargetException
        NoSuchFieldException
        NoSuchMethodException
        CloneNotSupportedException
        InterruptedException

산술 예외
        IndexOutOfBoundsException
        ArrayIndexOutOfBoundsException
        StringIndexOutOfBoundsException
        ArrayStoreException
        ClassCastException
        EnumConstantNotPresentException
        IllegalArgumentException
        IllegalThreadStateException
        NumberFormatException
        IllegalMonitorStateException
        IllegalStateException
        NegativeArraySizeException
        NullPointerException
        SecurityException
        TypeNotPresentException
        UnsupportedOperationException

java.net
        HttpRetryException
        SocketTimeoutException
        MalformedURLException
        ProtocolException
        SocketException
        BindException
        ConnectException
        NoRouteToHostException
        PortUnreachableException
        UnknownHostException
        UnknownServiceException
        URISyntaxException

java.text
        ParseException

java.time
        DateTimeException
        
java.time.zone
        ZoneRulesException

 

  • 연결된 예외 (Chained Exception)
    • 예외는 다른 예외를 유발할 수 있습니다.
    • 예외 A가 예외 B를 발생시켰다면, 예외 A는 B의 원인 예외입니다.
    • 원인 예외를 새로운 예외에 등록한 후 다시 새로운 예외를 발생시키는데, 이를 예외 연결이라고 합니다.
    • 예외를 연결하는 이유
      • 예외를 연결하는 이유는 여러 가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위함입니다.
      • checked exception을 unchecked exception으로 포장(wrapping) 하는데 유용하게 사용되기도 합니다.
  • 원인 예외를 다루기 위한 메소드
    • initCause()
      • 지정한 예외를 원인 예외로 등록하는 메소드
    • getCause()
      • 원인 예외를 반환하는 메소드
  • 실제로 예외 처리는 방법 : 예외 복구, 예외 처리 회피, 예외 전환

 

1. 예외 복구 

더보기
public String getDataFromAnotherServer(String dataPath) {
    try {
        return anotherServerClient.getData(dataPath).toString();
    } catch (GetDataException e) {
        return defaultData;
    }
}
  • 실제로 try-catch로 예외를 처리하고 프로그램을 정상 상태로 복구하는 방법입니다.
  • 가장 기본적인 방식이지만, 현실적으로 복구가 가능한 상황이 아닌 경우가 많거나 최소한의 대응만 가능한 경우가 많기 때문에 자주 사용되지는 않습니다. 문제가 발생했는데 defaultData를 반환한다는 점에서 임시방편에 불과함.

 

2. 예외 처리 회피

 

더보기
public void someMethod() throws Exception { ... }

----------------------------------------------------------

public void someIrresponsibleMethod() throws Exception {
    this.someMethod();
}
  • 이렇게 처리하면, someMethod()에서 발생한 에러가 someIrresponsibleMethod()의 throws를 통해서 그대로 다시 흘러나가게 되겠죠, 물론 같은 객체 내에서 이런 일은 하지는 않습니다, 예외 처리 회피를 보여드리기 위한 단순한 예시 코드입니다.
  • 관심사를 분리해서 한 레이어에서 처리하기 위해서 이렇게 에러를 회피해서 그대로 흘러 보내는 경우도 있습니다.

 

3. 예외 전환

더보기
public void someMethod() throws IOException { ... }

public void someResponsibleMethod() throws MoreSpecificException {
    try {
        this.someMethod();
    } catch (IOException e) {
        throw new MoreSpecificException(e.getMessage());  // MoreSpecificException는 예시
    }
}
  • 예외 처리 회피하기의 방법과 비슷하지만, 조금 더 적절한 예외를 던져주는 경우입니다.
  • 보통은 예외 처리에 더 신경 쓰고 싶은 경우나, 오히려 RuntimeException처럼 일괄적으로 처리하기 편한 예외로 바꿔서 던지고 싶은 경우 사용합니다.

 

 

'Java > Java 문법' 카테고리의 다른 글

Java에서 난수 만들기  (2) 2024.09.13
Java 문법 10 (제네릭)  (0) 2024.09.10
Java 문법 8 (인터페이스)  (0) 2024.09.06
Java 문법7 (상속)  (3) 2024.09.06
`Java 문법 6 (클래스)  (4) 2024.09.05