ETC/도서
[자바의 신] 14장. 다 배운 것 같지만, 예외라는 중요한 것이 있어요
by sorryisme
2024. 9. 27.
try catch
package exceptionExample;
public class ExceptionExample {
public static void main(String[] args) {
ExceptionExample exceptionExample = new ExceptionExample();
exceptionExample.arrayOutofBounds();
}
public void arrayOutofBounds() {
int[] intArray = new int[5];
try {
System.out.println(intArray[5]);
System.out.println("this code should run");
} catch (Exception e) {
System.err.println("Exception occured");
}
System.out.println(" code must run");
}
}
- try-catch에서 예외가 발생하지 않을 경우
- try 내에 있는 모든 문장이 실행되고 try catch 문장 이후 내용이 실행된다
- try-catch에서 예외가 발생하는 경우
- try 내에서 예외가 발생한 이후 문장들은 실행되지 않는다
- catch 내에 문장은 반드시 실행 그 이후 try catch 문장 이후 내용이 실행된다
try-catch에서 적응하기 힘든 변수 선언
- try 블록 내에서 선언한 변수를 catch 내에서 사용할수 없다
public class ExceptionVariable {
public static void main(String[] args) {
ExceptionVariable exceptionVariable = new ExceptionVariable();
exceptionVariable.checkVariable();
}
public void checkVariable() {
int[] intArray = null;
try {
intArray = new int[5];
System.out.println(intArray[5]);
} catch (Exception e) {
System.err.println(intArray.length);
}
System.out.println("this Code must run");
}
}
// 출력값 5
- 하지만 위와 같이 null이라고 지정하더라도 예외가 발생한 순간 이미 배열이 할당된다
- 그렇기에 catch에서 사용하는 변수는 블록 앞에서 선언해줘야한다
finally
- 자바에서 예외처리할 때 finally는 어떠한 경우에서도 실행하라는 의미
- 코드의 중복을 피하기 위해서 필요하다
두개 이상의 catch
package exceptionExample;
public class MultiCatchSample {
public static void main(String[] args) {
MultiCatchSample multiCatchSample = new MultiCatchSample();
multiCatchSample.multiCatch();
}
public void multiCatch() {
int[] intArray = new int[5];
try {
System.out.println(intArray[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array Index Out of Bound Exception");
} catch (Exception e) {
System.err.println(intArray.length);
}
}
}
- 여러 개의 catch 블록을 만들어서 사용해도 전혀 상관없다
- 모든 예외의 부모 클래스는 java.lang.Exception 클래스이다
예외의 종류는 세 가지다
- checked exception
- error
- runtime exception 혹은 unchecked exception
- error와 unchecked exception을 제외한 나머지가 checked exception이다
error
- 자바 프로그램 밖에서 발생된 에러
- Error로 끝나면 에러
- 프로그램 안에서 발생했는지 밖에서 발생했는지
- Error는 프로세스에 영향을 주고 Exception은 쓰레드에만 영향을 준다
runtime Exception(unchecked Exception)
- 예외가 발생할 것을 미리 감지 못할 때 발생
- NullPointException
- IndexOutofBoundException
모든 예외의 할아버지는 java.lang.Throwable 클래스
- Exception과 Error의 공통 부모 클래스는 Throwable
- 많이 사용하는 메소드
- getMessage() : 예외 메세지를 String 형태로 받는다
- toString() : 예외 클래스 이름도 같이 제공 받는다
- printStackTrace() : 예외 메세지 출력하고 호출 관계를 출력해준다
package exceptionExample;
public class ThrowableSample {
public static void main(String[] args) {
ThrowableSample throwableSample = new ThrowableSample();
throwableSample.throwable();
}
public void throwable() {
int[] intArray = new int[5];
try {
intArray = null;
System.out.println(intArray[5]);
} catch (Throwable t) {
System.err.println(t.getMessage());
System.err.println(t.toString());
t.printStackTrace();
}
}
}
난 예외를 던질 거니깐 throws라고 써 놓을게
package exceptionExample;
public class ThrowSample {
public static void main(String[] args) {
ThrowSample sample = new ThrowSample();
sample.throwException(13);
}
public void throwException (int number) {
try {
if(number > 12) {
throw new Exception("Number is over than 12");
}
System.out.println("Number is " + number);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- try 블록 내에서 throw라고 예약어를 명시한 후 예외 클래스의 객체를 생성하면 된다
- 만약에 해당하는 예외가 없다면 발생된 예외는 메소드 밖으로 던져 버린다
- 이럴때 사용하는 것이 메소드의 throws 구문이다
public void throwException (int number) throws Exception {
if(number > 12) {
throw new Exception("Number is over than 12");
}
System.out.println("Number is " + number);
}
- 호출한 메소드에서 try - catch 묶거나
- throws로 다시 한 번 처리해야한다
내가 예외를 만들 수 있다구?
- Error가 아닌 Exception을 처리하는 예외 클래스는 개발자가 임의로 추가해서 만들 수 있다
- Throwable이나 그 자식 클래스를 상속받아야 한다
- java.lang.Exception 클래스를 상속 받는 것이 좋다
package exceptionExample;
public class MyException extends Exception {
public MyException() {
}
public MyException(String s) {
super(s);
}
}
자바 예외 처리 전략
- 커스템 예외 클래스의 경우 실행 시 발생할 확률이 높다면 런타임 예외로 만드는 것이 좋다
- extends RuntimeException
- try catch로 묶지 않아도 컴파일 시 예외가 발생하지 않는다
- 하지만 방어코드로서 메소드를 호출하는 곳에서 try catch로 처리해주는 것이 좋다