Error와 Exception은 같다고 생각할 수도 있지만 사실 큰 차이가 있습니다.
오류(Error)는 시스템이 종료되어야 할 수준의 상황과 같이 수습할 수 없는 심각한 문제를 의미합니다. 개발자가 미리 예측하여 방지할 수 없습니다.
반면 예외(Exception)는 개발자가 구현한 로직에서 발생한 실수나 사용자의 영향에 의해 발생합니다. 오류와 달리 개발자가 미리 예측하여 방지할 수 있기에 상황에 맞는 예외처리(Exception Handle)를 해야합니다.
프로그램이 실행 중 어떤 원인에 의해서 오작동을 하거나 비정상적으로 종료되는 경우를 프로그램 오류라 하고, 프로그램 오류에는 에러(error)와 예외(exception) 두 가지로 구분할 수 있습니다. 에러는 메모리 부족이나 스택오버플로우와 같이 발생하면 복구할 수 없는 심각한 오류이고, 예외는 발생하더라도 수습할 수 있는 비교적 덜 심각한 오류입니다. 이 예외는 프로그래머가 적절히 코드를 작성해주면 비정상적인 종류를 막을 수 있습니다.
Error의 상황을 미리 미연에 방지하기 위해서 Exception 상황을 만들 수 있으며, java에서는 try-catch문으로 Exception handling을 할 수 있습니다.
잘못된 하나로 인해 전체 시스템이 무너지는 결과를 방지하기 위한 기술적인 처리입니다. JAVA에서는 예외와 에러도 객체로 처리합니다.
예외가 주로 발생하는 원인
오류와 예외 모두 자바의 최상위 클래스인 Object를 상속받습니다. 그리고 그 사이에는 Throwable이라는 클래스와 상속관계가 있네요. 이 클래스에 대한 공식문서를 읽어보면 이 클래스의 객체에 오류나 예외에 대한 메시지를 담는다는 이야기가 나옵니다. 그리고 예외가 연결될 때(chained exception) 연결된 예외의 정보들을 기록하기도 한다고 합니다. 이 Throwable 객체가 가진 정보와 할 수 있는 행위는 getMessage()
와 printStackTrace()
라는 메서드로 구현되어 있는데요. 당연히 이를 상속받은 Error와 Exception에서 두 메서드를 사용한다는 사실은 유추할 수 있을 겁니다. 우리가 실제로 보는 에러 코드들은 이 두 메서드를 이용해서 콘솔상에 나타납니다.
Error는 시스템 레벨에서 발생하여, 개발자가 어떻게 조치할 수 없는 수준을 의미합니다.
예외는 개발자가 구현한 로직에서 발생하며 개발자가 다른 방식으로 처리가능한 것들로 JVM은 정상 동작합니다.
Checked Exception : 예외처리가 필수이며, 처리하지 않으면 컴파일되지 않습니다. JVM 외부와 통신(네트워크, 파일시스템 등)할 때 주로 쓰입니다.
Unchecked Exception : 컴파일 때 체크되지 않고, Runtime에 발생하는 Exception을 말합니다.
JAVA에서 모든 예외가 발생하면 (XXX)Exception 객체를 생성합니다. 예외를 처리하는 방법에는 크게 2가지가 있습니다.
다른 메소드의 일부분으로 동작하는 경우엔 던지는 것을 추천합니다.
로직 중에 예외가 발생할지도 모르는 부분에 try ~ catch 구문으로 보험 처리합니다.
.close()
가 있습니다.예외 처리를 현재 메소드가 직접 처리하지 않고 호출한 곳에다가 예외의 발생 여부를 통보합니다. 호출한 메소드는 이걸 또 던질건지 직접 처리할 건지 정해야합니다. (return보다 강력합니다.)
public class ThrowsEx {
public void call_A() throws Exception {
call_B();
}
private void call_B() throws Exception {
call_C();
}
private void call_C() throws Exception {
System.out.println(1 / 0);
}
public static void main(String[] args) throws Exception {
ThrowsEx test = new ThrowsEx();
test.call_A();
}
}
실행 결과는 아래와 같습니다.
Exception in thread "main" java.lang.ArithmeticException: / by zero
at exception.ThrowsEx.call_C(ThrowsEx.java:13)
at exception.ThrowsEx.call_B(ThrowsEx.java:9)
at exception.ThrowsEx.call_A(ThrowsEx.java:5)
at exception.ThrowsEx.main(ThrowsEx.java:18)