2021. 4. 25. 16:07ㆍJava
오류의 종류
- 에러 (Error)
: 에러 발생 시, 프로그램이 비정상 종료 된다.
: 정상 실행 상태로 돌아갈 수 없다.
- 예외 (Exception)
: 사용자의 잘못된 조작 또는 개발자의 잘못된 프로그래밍으로 인한 오류
: 예외 발생 시, 프로그램이 종료되지만 예외처리를 해줄 경우 정상 실행 상태로 되돌릴 수 있다.
=> 예외처리의 목적은 프로그램을 정상 실행 상태로 돌리기 위함
Exception 의 종류
- 일반 예외 (= Complie Exception 또는 Checked Exception)
: 컴파일 시점에 예외가 발생함
- 실행 예외 (=RuntimeException 또는 UnChecked Exception)
: 실행 시점에 예외가 발생함
[RuntimeException] 자주 발생하는 Exception
- ArrayIndexOutOfBoundsException
- NullPointerException
- NumberFormatException
- ArithmeticException
- ClassCastException
ArrayIndexOutOfBoundsException
- 자료형에 존재하지 않는 인덱스 값를 불러오려고 할 때 발생
int[] arr = new int[5];
int check = arr[5];
NullPointerException
- null 값을 조작하거나, 초기화되지 않은 객체의 변수나 메소드를 접근하려고 할 때 발생
String str = null;
String check = str.toString();
NumberFormatException
- 문자를 숫자로 변경 시, 발생
String str1 = "100";
String str2 = "100가";
int num1 = Integer.parseInt(str1);
int num2 = Integer.parseInt(str2);
ArithmeticException
- 수학적인 계산의 과정에서 발생
int num = 10/0;
ClassCastException
- 객체의 형을 변환할 때 객체 타입 변환이 적절하지 않을때 발생
- Class 뿐만 아니라 Interface 또한 형의 변환 또한 적절하지 않을때 발생한다.
class A {}
class B extends A {}
class C extends A {}
public class Example {
public static void main(String[] args) {
// 정상
A a1 = new B();
B b1 = (B) a1; // B 로 다운캐스팅
// 오류
A a2 = new B();
C c1 = (C) a2; // C 로 다운캐스팅 -> ClassCastException 발생
}
}
Exception Handling
- Java 는 RuntimeException 을 처리할 수 있는 구문을 4가지 제공한다.
1. 예외가 발생한 메서드 안에서 처리 (try-catch-finally)
2. 예외가 발생한 메서드를 호출한 곳에서 처리 (throws)
3. 강제로 예외를 발생시켜서 처리 (throw)
4. 사용자 예외를 생성하여 처리
1. 예외 처리 코드 (try-catch-finally)
- 예외가 발생하기 전, 예외 처리 코드를 작성하면 프로그램의 종료를 막고 정상 실행을 유지할 수 있다.
- Checked Exception 는 반드시 작성해야한다. (컴파일이 안되므로...)
- UnChecked Exception 는 컴파일러가 체크해주지 않으므로 개발자의 경험으로 작성한다.
- [정상 실행이 되었을 경우]
: try 블럭은 무조건 실행된다.
: catch 블럭은 실행되지 않는다. (다중 catch 블럭 가능)
: finally 블럭은 무조건 실행된다. (Optional)
- [비정상 실행이 되었을 경우]
: try 블럭은 무조건 실행된다.
: catch 블럭은 무조건 실행된다.
: finally 블럭은 무조건 실행된다. (Optional)
참고
- 다중 catch 구문 작성 시, 상위 클래스가 위에 있으면 안된다.
// 틀린 코드 -> Exception 의 최고 조상 Exception 이 catch 구문 맨 위에 존재함
try {
} catch (Exception e) {
} catch (ArrayIndexOutOfBoundsException e) {
} finally {
}
- JDK 1.7부터 하나의 catch 구문에서 | (파이프)를 사용하여 복수 개의 예외를 처리할 수 있다.
try {
} catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
} catch (Exception e) {
}
2. 예외 던지기 (throws)
- 메서드 선언부 끝에 키워드 throws 를 붙여서 작성한다.
- 키워드가 붙은 메소드에서 예외발생 시, Exception 처리하라고 호출부로 던진다.
- 호출한 곳에서는 예외를 받기 위해 반드시 예외처리 코드가 있어야 한다.
- 아래 코드는 test() 메소드에서 throws 키워드를 사용하였다.
- test() 에서 예외 발생 시, main() 메서드가 처리해줘야 한다.
- 그러므로 main() 메서드에서 try-catch 구문을 작성해주었다.
public class Example {
public static void main(String[] args) {
try {
test();
} catch (Exception e) {
}
}
public static void test() throws Exception { }
}
3. 강제로 예외 발생 시키기 (throw)
- 강제로 예외를 발생 시켜 호출한 곳에 Exception 을 던질 수 있다.
- throws 키워드를 이용해 예외를 던지지 않고, 바로 처리하고 싶다면 test() 에서 try-catch 를 사용하자.
public class Example {
public static void main(String[] args) {
try {
test();
} catch (Exception e) {
e.getMessage();
}
}
public static void test() throws Exception {
throw new Exception("예외 강제로 발생");
}
}
4. 사용자정의 Exception 처리
- 따로 Exception 종류를 상속 받아 커스터마이징 해주어 예외 발생을 의도한다.
- 자바 표준API 에서 제공하지 않는 예외는 직접 프로그래밍 하여 만들어야 한다.
- 순서
1. 관례적으로 Exception 을 붙여 준다.
2. 일반 Exception 인지 RuntimeException 인지 선택하여 상속 받는다. (보통 관리 차원에서 Exception 으로 함)
3. 기본 생성자를 하나 선언하자.
4. 조상 클래스인 Exception 의 생성자를 반드시 호출하여 호출이유를 적어주자.
class CustomException extends Exception {
public CustomException() {
}
public CustomException(String message) {
super(message);
}
}
public class Example {
public static void main(String[] args) {
try {
// 3. 예외 받기
test();
} catch (CustomException e) {
// 4. 사용자정의 Exception 처리
System.out.println(e.getMessage());
} catch (Exception e) {
e.getMessage();
}
}
public static void test() throws Exception {
// 1. 강제로 예외 발생
throw new CustomException("사용자정의 Exception !!");
// 2. main() 로 예외 던지기
}
}
참고
e.getMessage()
- 예외를 발생시킬 때, 생성자의 매개변수 값으로 사용한 String return 값
e.printStackTrace()
- 예외 발생 코드를 추적하여 로그들을 전부 console 에 출력
- 개발자 전용이며 프로그램 Test 그리고 Debugging 할 때 유용하다.
- 개발 시에 자주 사용하며, 배포 시 주석처리 또는 제거해야하는 코드
연습
1. 코드를 보고 이해 해보자.
public class Example {
public static void main(String[] args) {
try {
// 클래스를 찾아 동적으로 인스턴스화
Class stringClass = Class.forName("java.lang.String");
// 위 코드가 에러날 경우, 아래 코드는 실행 되지 않음
System.out.println("== String 클래스를 찾았습니다.");
System.out.println("==[클래스명+패키지]: " + stringClass.getName());
System.out.println("==[클래스명]: " + stringClass.getSimpleName());
} catch (ClassNotFoundException e) {
System.out.println("== String 클래스를 찾지 못했습니다.");
} finally {
System.out.println("== 프로그램을 종료하였습니다.");
}
}
}
2. 코드를 보고 이해 해보자.
public class Example {
public static void main(String[] args) throws Exception {
throw new NullPointerException("JVM 에게 예외 던지기!");
}
}
'Java' 카테고리의 다른 글
[Java] 오브젝트(Object) 란? - 특징과 사용법 (0) | 2021.06.17 |
---|---|
[Java] 쓰레드(Thread) 란? 특징과 사용법 (0) | 2021.05.04 |
[Java] 스트림(Stream) 이란? - 특징과 사용법 (0) | 2021.04.24 |
[Java] Java8 에 새롭게 추가된 기능을 알아보자 (0) | 2021.04.12 |
[Java] 리플렉션(Reflection) 이란? (0) | 2021.03.10 |