✔️이 글은 [자바의 신 - 이상민 지음] 도서를 바탕으로 정리한 글입니다.
자바에서 매우 중요한 예외
자바에서의 예외는 "우리가 예상한, 혹은 예상치도 못한 일이 발생하는 것을 미리 예견하고 안전장치를 하는 것"을 말한다.
예외적인 일이 발생하면 "예외"라는 것을 던진다.
대표적인 예로 null인 객체에 메소드를 호출하는 경우가 있다.
try-catch는 짝이다
컴파일은 정상적으로 되지만 예상치못한 예외가 발생할 수 있다.
그러한 예외 상황이 발생할만한 코드들을 try로 묶어주고, catch로 예외처리를 해준다.
try-catch 블록
try {
예외가 발생할만한 코드
}
catch (Exception e) {
예외가 발생했을 때 수행할 코드
}
catch 뒤에 오는 소괄호에는 Exception이라는 클래스 이름과 매개변수 이름 같은 e를 써주었다.
catch문 안에서 에러 메시지를 출력할 때는 System.err.println()이라는 메소드를 사용해 출력결과를 다른 색으로 표현해주는 것이 좋다.
try-catch에서 예외가 발생하지 않을 경우
try 내에 있는 모든 문장이 실행되고, try-catch 문장 이후의 내용이 실행된다.
try-catch에서 예외가 발생하는 경우
try 내에서 예외가 발생한 이후의 문장은 실행되지 않는다.
catch 내에 있는 문장은 반드시 실행되고, try-catch 문장 이후의 내용이 실행된다.
try-catch를 사용하면서 처음에 적응하기 힘든 변수 선언
try 블록은 중괄호로 묶여 있는 블록으로 try 블록 내에서 선언한 변수는 catch나 다른 곳에서 사용할 수 없다는 점을 주의해야 한다.
finally야~넌 무슨 일이 생겨도 반드시 실행해야 돼
try-catch 구문에 추가로 finally 구문을 쓸 수 있다.
finally는 어떤한 경우에도 실행되는 구문으로 예외 발생 여부와 상관없이 실행된다.
finally는 코드의 중복을 피하기 위해 필요한데 이 책의 26장을 이해할 수 있다.
두 개 이상의 catch
catch의 소괄호 안에는 예외의 종류를 명시해준다. 위 try-catch블록 소개에서처럼 꼭 Exception e라고 쓸 필요가 없다는 의미이다.
catch 블록은 여러개 만들어줘도 되는데 선언하는 순서가 매우 중요하다!
모든 예외의 부모 클래스는 java.lang.Exception 클래스이다. java.lang에 선언되어 있기 때문에 별도로 import할 필요는 없다.
Exception 클래스가 모든 클래스의 부모 클래스이고, ArrayindexOutOfBoundsException의 경우 Exception의 자식 클래스이기 때문에 catch 블록을 써줄 때 Exception이 맨 마지막에 와줘야 자식 클래스 예외들이 수행될 수 있다.
또 한번 catch되면 그 뒤에 오는 catch 블록들은 무시되기 때문에 순서를 잘 배정해줘야 한다.
catch 블록 중 발생한 예외와 관련있는 블록이 없으면, 예외가 발생되면서 해당 쓰레드는 종료된다. 따라서, 마지막 catch 블록에는 Exception을 써주는 것이 좋다.
예외의 종류는 세 가지다
- error(이하 에러) : 자바 프로그램 밖에서 발생한 예외로 자바 프로그램이 제대로 동작하지 못하는 경우, error는 프로세스에 영향을 주고, exception은 쓰레드에만 영향을 줌
- runtime exception 혹은 unchecked exception(이하 런타임 예외) : 예외가 발생할 것을 미리 감지하지 못했을 때 발생, RuntimeException을 확장한 예외들로 컴파일때는 예외가 발생하지 않았지만 실행시에 발생할 가능성이 있는 것
- checked exception : error와 unchecked exception을 제외한 모든 예외
모든 예외의 할아버지는 java.lang.Throwable 클래스다
Exception과 Error의 공통 부모 클래스는 Object 클래스와 java.lang.Throwable 클래스이다.
Exception과 Error는 Throwable로 처리해도 무방하다. 상속관계가 이런건 Exception과 Error가 성격은 다르지만, 모두 동일한 이름의 메소드를 사용하여 처리할 수 있도록 하기 위함이다.
Throwable에 선언된 생성자
- Throwable()
- Throwable(String message)
- Throwable(String message, Throwable cause)
- Throwable(Throwable cause)
Throwable에서 선언되어 있고, Exception에서 Overriding한 메소드
- getMessage() : 에외 메시지를 String 형태로 제공 받음. 어떤 예외가 발생했는지 확인할 때 유용함
- toString() : 예외 메시지를 string 형태로 제공 받음. getMessage()보다는 더 자세하게 예외 클래스 이름도 같이 제공
- printStackTrace() : 첫줄에는 예외 메시지를 출력하고, 두번째 줄부터는 예외가 발생하게 된 메소드들의 호출관계 (스택 트레이스)를 출력. 로그가 많이 쌓일 수 있어 개발할때만 사용하는 것을 권장
난 예외를 던질 거니까 throws라고 써 놓을게
try 블록 내에서 trhow라고 명시한 후 개발자가 예외 클래스의 객체를 생성하면 예외를 발생시킬 수 있다.
try {
...
throw new Exception(...);
}
catch(Exception e) {
}
throw가 수행되면 그 문장 이후에 있는 try 블록 내의 문장들은 수행되지 않고 catch 블록으로 이동한다.
catch 블록 중에 throw한 예외와 같거나 상속 관계에 있는 예외가 있다면 그 블록에서 예외를 처리하지만 해당하는 예외가 없다면 예외가 발생된 메소드를 호출한 메소드로 던진다. 이럴때 throws를 사용한다.
메소드의 소괄호 뒤에 throws 예외 클래스를 적어주면 try-catch 문을 묶지 않아도 예외를 throw해도 컴파일이 가능하다.
try-catch가 없고 throws를 해준 메소드를 호출한 메소드에서는 반드시 try-catch 블록으로 throws한 메소드를 감싸주어야 한다. 이 방법보다는 throws한 메소드 내에 try-catch 문을 써주는 것이 더 좋은 방법이다.
throws의 경우는 여러 예외 클래스를 나열할 수 있어 여러 예외를 처리할 수 있다.
내가 예외를 만들 수 있다구?
Error 클래스는 개발자가 수정해서는 안되지만, Exception을 처리하는 예외 클래스는 Throwable 클래스이나 그 자식의 상속을 받으면 개발자가 임의로 추가해줄 수 있다. Exception을 처리하는 클래스라면 Exception 클래스를 상속받는게 더 좋다.
자바 예외 처리 전략
자바에서 예외를 처리할 때는 표준을 잡고 진행해야 한다.
일반적으로 unchecked exception인 RuntimeException이 발생하는 메소드가 있다면, 그 메소드를 호출하는 메소드는 try-catch로 묶어주지 않더라고 컴파일 때 문제가 발생하지는 않지만 예외가 발생할 확률은 높으므로 try-catch로 묶어줘야 한다.
또 catch 문을 공백으로 두면 예외 분석이 어려워지므로 꼭 로그 처리와 같은 예외처리를 해주는 것이 좋다.
추가로 더 많은 예외 처리 전략들은 구글링을 통해 알아보자!
정리해 봅시다
1. 예외를 처리하기 위한 세 가지 블록에는 어떤 것이 있나요?
try,catch,finally
2. 1의 답 중에서 "여기에서 예외가 발생할 것이니 조심하세요"라고 선언하는 블록은 어떤 블록인가요?
try
3. 1의 답 중에서 "예외가 발생하든 안하든 얘는 반드시 실행되어야 됩니다."라는 블록은 어떤 블록인가요?
finally
4. 예외의 종류 세 가지는 각각 무엇인가요?
checked exception, error, unchecked exception
5. 프로세스에 치명적인 영향을 주는 문제가 발생한 것을 무엇이라고 하나요?
error
6. try나 catch 블록 내에서 예외를 발생시키는 키워드는 무엇인가요?
throw
7. 메소드 선언시 어떤 예외를 던질 수도 있다고 선언할 때 사용하는 키워드는 무엇인가요?
throws
8. 직접 예외를 만들 때 어떤 클래스의 상속을 받아서 만들어야만 하나요?
Exception을 확장해서 만들 수 있다.
하지만 이렇게 되면 무조건 해당 예외를 던지는 메소드에서 try-catch로 묶어줘야 하므로 RuntimeException 클래스를 확장해서 선언하는 것이 더 좋다.
'도서 > 자바의 신' 카테고리의 다른 글
[도서/자바의 신] #16 클래스 안에 클래스가 들어갈 수도 있구나 (0) | 2022.12.25 |
---|---|
[도서/자바의 신] #15 String (1) | 2022.12.25 |
[도서/자바의 신] #13 인터페이스와 추상클래스, enum (1) | 2022.12.23 |
[도서/자바의 신] #12 모든 클래스의 부모 클래스는 Object에요 (0) | 2022.12.23 |
[도서/자바의 신] #11 매번 만들기 귀찮은데 누가 만들어 놓은 거 쓸 수 없나요? (0) | 2022.12.22 |