티스토리 뷰
프로그램에서의 오류
컴파일 오류(compile error)
프로그램 코드 작성 중 발생하는 문법적 오류
최근에는 개발 환경(eclipse)에서 대부분 컴파일 오류는 detection 됨.
실행 오류(runtime error)
실행 중인 프로그램이 의도하지 않은 동작(bug)을 하거나 프로그램이 중지 되는 오류
실행 오류 또는 비정상 종료가 되는 경우 시스템의 심각한 장애를 일으킴.
실행 오류는 개발자가 해결 가능하다.
시스템 오류(error): 컴퓨터 하드웨어의 고장으로 인해 가상 머신에서 응용프로그램 실행 오류가 발생하는 것. 너무 심각해서 프로그래머가 처리할 수 있는 방법이 없는 오류다. 동적 메모리가 없는 경우, 스택 메모리 오버플로우 등
예외(Exception): 잘못된 사용 또는 코딩으로 인한 오류, 프로그램에서 제어할 수 있는 오류
읽어들이려는 파일이 존재하지 않거나 네크웍이나 DB 연결이 안되는 경우 등
예외가 발생하면 프로그램은 곧바로 종료된다는 공통점이 있지만, 예외 처리를 통해 계속 실행 상태를 유지할 수 있다.
예외 처리
예외 처리는 프로그램 실행 중 발생할 수 있는 예상치 못한 상황(예외)을 관리하는 방법이다.
예외 처리를 통해 프로그램의 비정상적인 종료를 막고, 예외 상황을 보다 적절하게 처리하여 프로그램의 안정성과 신뢰성을 높일 수 있다.
자바는 안정성이 중요한 언어로 대부분 프로그램에서 발생하는 오류에 대해 문법적으로 예외처리를 해야 한다.
예외 처리의 중요성
- 프로그램의 바정상 종료를 피하여 시스템이 원활히 실행되도록 한다.
- 실행 오류가 발생한 경우 오류의 과정을 재현하는 것은 현실적으로 힘들다.
- 오류가 발생한 경우 log를 남겨서 추후 log 분석을 통해 그 원인을 파악하여 bug를 수정하는 것이 중요하다.
예외 2가지 1. 일반 예외(Exception) 컴파일러가 예외 처리 코드 여부를 검사하는 예외 2. 실행 예외(Runtime Exception) 컴파일러가 예외 처리 코드 여부를 검사하지 않는 예외 |
예외가 발생하면 클래스로부터 객체를 생성한다. 이 객체는 예외 처리 시 사용된다.
자바의 모든 에러와 예외 클래스는 Throwable을 상속받아 만들어지고, 추가적으로 예외 클래스는 java.lang.Exception 클래스를 상속 받는다.
실행 예외는 RuntimeException과 그 자식 클래스에 해당한다. 그 밖의 예외 클래스는 모두 일반 예외이다.
예외 처리 예시1)
try {
// 예외가 발생할 수 있는 코드
} catch (ExceptionType1 e) {
// ExceptionType1 예외를 처리하는 코드
} catch (ExceptionType2 e) {
// ExceptionType2 예외를 처리하는 코드
}
예외 처리 예시2)
try {
// 예외가 발생할 수 있는 코드
} catch (Exception e) {
// 예외 처리 코드
} finally {
// 항상 실행되는 코드
}
예외 처리 코드 : try-catch-finally 블록 => 생성자 내부, 메서드 내부에서 작성된다.
finally 블록: try 블록의 실행 여부와 관계 없이 항상 실행되어야 하는 코드(예: 자원 해제 로직)를 포함한다. finally 블록은 모든 catch 블록 다음에 자원을 닫아주어야 할때 온다. try 블록과 catch 블록에서 return 문(메서드 종료)을 사용하더라도 finally 블록은 항상 실행된다.
ArithmeticException
어떤 수를 0으로 나누는 경우
정수 10을 0으로 나누었기 때문에 ArithmeticException 예외가 발생하였다. 현재 예외처리를 하고 있지 않기 때문에 예외가 발생하는 즉시 프로그램이 종료되었다. 예외가 발생한 지점 이후의 문장들은 실행되지 않는다.
ArrayIndexOutOfBoundsException
배열을 참조하는 인덱스가 잘못된 경우
<오류 해석>
메인 스레드에서 ArrayIndexOutOfBoundsException 예외 발생: 배열 크기 5인데 인덱스 길이가 5를 벗어남.(인덱스 길이는 4여야 함.)
ch14 패키지의 ArrayExceptionHandling 클래스의 main 스레드의 9 라인(System.out.println(arr[i])에서 예외 발생함.
여기에 예외 처리 코드를 추가하자면, try 블록에서 NullPointerException이 발생하면 catch 블록을 실행해서 예외를 처리하도록 하고 예외 발생 여부와 상관 없이 finally 블록(자원(리소스)을 닫아주어야 할 때)을 실행하여 마무리하면 된다.
예외 처리)
NumberFormatException
숫자 형식 예외
6 라인에서 Integer.parseInt() 메서드를 통해 문자가 숫자로 변환이 되어서 예외가 발생하였다.
예외 처리)
NullPointerException(실행 예외)
null 객체를 참조하는 경우 발생
가리키는 객체의 주소가 없거나 객체를 생성하지 않았을 때 발생한다.
예시1)
<오류 해석>
main 스레드에서 예외 발생(java.lang.NullPointerException): data 가 null이라서 String.length() 를 호출할 수 없다
ch14 패키지의 ExceptionHandlingExample 클래스의 printLength() 메서드 내의 6라인에서
ch14 패키지의 ExceptionHandlingExample 클래스의 main 함수 내의 12라인에서
위의 코드는 12라인에서 문자열 대신 null을 입력하여 6라인에서 NullPointerException이 발생한 것이다.
NullPointerException은 참조 변수가 null인 상태에서 필드나 메서드에 접근할 경우 발생한다.
예외 처리)
ClassNotFoundException(일반 예외)
ClassPath 위치에서 주어진 클래스를 찾지 못했을 경우 발생
java.lang.String2 클래스는 찾을 수 없다는 오류가 뜬다.
FileNotFoundException
파일을 찾지 못했을 때 발생
예외 처리)
리소스 자동 닫기 리소스란 데이터를 제공하는 객체이다. 리소스는 사용하기 위해 열어야 하고, 사용이 끝나면 파일을 닫아야 한다.(예를 들어, 파일 내용을 읽기 위해 파일을 열어야 하며, 다 읽고 난 후에는 파일을 닫아야 다른 프로그램에서 사용할 수 있다. ) |
위의 코드에서 보면 demo.txt 파일의 내용을 읽기 위해 FileInputStream 리소스를 사용하는데, 예외 발생 여부와 상관없이 finally 블록에서 안전하게 close 한다.
이때 try-with-resources 블록을 사용하면 예외 발생 여부와 상관없이 리소스를 자동으로 닫아준다.
try-with-resources 블록을 사용하는 조건: 리소스는 java.lang.AutoCloseable 인터페이스를 구현해서 AutoCloseable 인터페이스의 close() 메서드를 재정의해야 한다.
<예외 종류 정리표>
분류 | 예외 | 설명 |
Runtime - Exception(실행 예외) | ArithmeticException | 어떤 수를 0으로 나누는 경우 |
NullPointerException | null 객체를 참조하는 경우 | |
ClassCastException | 적절치 못하게 클래스를 형변환하는 경우 | |
NegativeArraySizeException | 배열의 크기가 음수값인 경우 | |
OutOfMemoryException | 사용 가능한 메모리가 없는 경우 | |
NoClassDefFoundException | 원하는 클래스를 찾지 못하였을 경우 | |
ArrayIndexOutOfBoundsException | 배열을 참조하는 인덱스가 잘못된 경우 |
분류 | 예외 | 설명 |
Checked - Exception(일반 예외) | ClassNotFoundException | 클래스가 발견되지 않을 때 |
IOException | 입출력 오류 | |
illegalAccessException | 클래스의 접근이 금지되었을 때 | |
NoSuchMethodException | 메서드가 발견되지 않았을 때 | |
NoSuchFieldException | 필드가 발견되지 않았을 때 | |
InterruptedException | 스레드가 다른 스레드에 의하여 중단되었을 때 | |
FileNotFoundException | 파일을 찾지 못했을 때 |
throws(예외 떠넘기기)
메서드 내부에서 예외가 발생할 때 try-catch 블록으로 예외 처리하는 것이 기본이지만,
메서드를 호출한 곳으로 예외를 떠넘길 수 있다.
throws는 메서드 선언부 끝에 작성하는데, 떠넘길 예외 클래스를 쉼표로 구분해서 나열하면 된다.
if (someCondition) {
throw new Exception("Custom Error Message");
}
----------------------------------------------------------------
public void someMethod() throws IOException, NullPointerException {
// 리턴타입 메서드명(매개변수) throws 예외 클래스1, 예외 클래스2...
// 예외가 발생할 수 있는 코드
}
throws 키워드가 붙어 있는 메서드에서 해당 예외 처리를 하지 않고 떠넘겼기 때문에 메서드를 호출하는 곳에서 예외를 받아서 처리해야 한다.
예시)
위의 코드에서는 main 함수에서 divide() 메서드가 호출되었고
divide() 메서드가 throws Exception(던져서 강제성 발생) 되어 divide() 메서드를 호출한 곳에서 예외처리를 하였다.
즉, throws Exception은 Exception 예외가 발생하면 상위 메서드(divide())로 예외를 던져서 처리하겠다는 의미이다.
나열해야 할 예외 클래스가 많을 경우에는 throws Exception 또는 throws Throwable 만으로 모든 예외를 간단히 떠넘길 수 있다.
main() 메서드에서도 throws 키워드를 사용해서 예외를 떠넘길 수 있는데, 결국 JVM 이 최종적으로 예외 처리를 하게 된다. JVM은 예외의 내용을 콘솔에 출력하는 것으로 예외 처리를 한다.
사용자 정의 예외
사용자 정의 예외 클래스 만드는 방법 1. 클래스를 설계 해서 상속 받아야 한다. 2. 활용할 수 있는 클래스에서 throws 와 throw 를 활용(Password 클래스에서 활용) 3. 코드 실행 시점에서 테스트 및 예외 처리 작성 |
예시)
정규식(Regular Expression, 줄여서 regex 또는 regexp)은 문자열을 처리할 때 사용되는 강력한 도구로,
복잡한 검색, 매칭, 치환 작업을 간단하고 유연하게 수행할 수 있도록 돕습니다.
특정한 규칙을 가진 문자열의 집합을 표현하는데 사용되며 이 규칙에 따라 문자열의 검색, 분할, 대체, 검증 등 다양한 작업을 자동화할 수 있습니다.
'Java' 카테고리의 다른 글
Java(중첩 클래스) (0) | 2024.05.06 |
---|---|
Java(String 클래스, StringBuffer 클래스, text block) (0) | 2024.05.04 |
Java(Thread/Multi-threading/synchronization) (0) | 2024.05.01 |
Java Swing(로또 게임 만들기) (0) | 2024.04.30 |
Java Swing(Event Listener/Key Listener) (0) | 2024.04.30 |