본 포스팅은 [이것이 자바다]의 내용을 참고하여 작성하였습니다.
1. 예외와 예외클래스
- 에러(Error): 컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용프로그램 실행 오류가 발생하는 것
- 예외(Exception): 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류
- 일반 예외(Exception): 컴파일하는 과정에서 예외 처리 코드가 필요한 지 검사함 (빨간줄)
- 실행 예외(Runtime Exception): 컴파일하는 과정에서 예외 처리 코드를 검사하지 않음
- 예외 처리(Exception Handling)을 통해 프로그램을 종료하지 않고 정상 실행 상태를 유지할 수 있다.
→ JVM은 예외가 Rumtime Exception을 상속했는지 여부를 보고 실행 예외를 판단한다!
2. 실행 예외(Runtime Exception)
1. NullPointerException
객체 참조가 없는 상태. null 값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생.
public class NullPointerExceptionExample {
public static void main(String[] args) {
String data null;
System.out.println("data.toString");
}
}
2. ArrayIndexOutOfBoundsException
배열에서 인덱스 범위를 초과하여 사용할 경우 발생.
public class ArrayIndexOutOfBoundsExceptionExample {
public static void main(String[] args) {
String data1 = args[0];
String data2 = args[1];
System.out.println("args[0]: " + data1);
System.out.println("args[1]: " + data2);
}
}
3. NumberFormatException
문자열을 숫자로 변환할 때, 숫자로 변환될 수 없는 문자가 포함되어있을 경우 발생.
public class NumberFormatExceptionExample {
public static void main(String[] args) {
String data1 = "100";
String data2 = "a100";
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2); // NumberFormatException 발생
int result = value1 + value2;
System.out.println(data1 + "+" data2 + "=" + result);
}
}
4. ClassCastException
억지로 타입 변환을 시도할 경우 발생한다.
public class except {
public static void main(String[] args) {
Dog dog = new Dog();
changeDog(dog);
Cat cat = new Cat();
changeCat(cat);
}
public static void changeDog(Animal animal) {
// if (animal instanceof Dog) {
Dog dog = (Dog) animal; // ClassCastException 발생 가능
// }
}
}
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
주석을 풀어주면 instanceof 연산을 사용하여 잘못된 매개값에 대한 예외 처리가 가능하다.
3. 예외 처리 코드
프로그램에서 예외가 발생했읕 경우 프로그램의 갑작스러운 종료를 막고, 정상 실행을 유지할 수 있도록 처리하는 코드이다.
try - catch - finally 블록을 이용.
try {
// 예외 발생 가능 코드
} catch(예외클래스 e) {
// 예외 처리
} finally {
// 항상 실행
}
try 블록의 코드에서 예외가 발생하면 즉시 실행을 멈추고 catch 블록으로 이동하여 예외 처리 코드를 실행한다. 그리고 finally 블록의 코드를 실행한다.
try 블록과 catch 블록에서 return문을 사용하더라도 finally 블록은 항상 실행된다.
4. 예외 종류에 따른 처리 코드
1. 다중 catch
try 블록 내부는 다양한 종류의 예외가 발생할 수 있기 때문에, 발생되는 예외별로 예외 처리 코드를 다르게 해야한다. 이 문제를 해결하기 위해 다중 catch 블록을 작성한다.
try {
// 1. ArrayIndexOutOfBoundsException 발생
// 2. NumberFormatException 발생
} catch(ArrayIndexOutOfBoundsException e) {
// 예외 처리1
} catch(NumberFormatException e) {
// 예외 처리2
}
2. catch 순서
다중 catch 블록을 작성할 때 주의할 점은, 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다. 만약 상위 예외 클래스의 catch 블록이 위에 있다면 하위 예외 클래스의 catch 블록은 실행되지 않는다.
try {
// 1. ArrayIndexOutOfBoundsException 발생
// 2. NumberFormatException 발생
} catch(Exception e) {
// 예외 처리1 (두 예외 모두 해당 catch 블록이 실행된다)
} catch(ArrayIndexOutOfBoundsException e) {
// 예외 처리2 (실행되지 않음!!)
}
3. 멀티 catch
하나의 catch 블록에서 여러 개의 예외를 처리할 수 있도록 하는 기능이다.
catch 괄호() 안에 동일하게 처리하고 싶은 예외를 | 로 연결하면 된다.
try {
// 1. ArrayIndexOutOfBoundsException 또는 NumberFormatException 발생
// 2. 다른 Exception 발생
} catch(ArrayIndexOutOfBoundsException | NumberFormatException e) {
// 예외 처리1
} catch(Exception e) {
// 예외 처리2
}
5. 자동 리소스 닫기
try - catch - finally 블록을 사용하면 예외 발생 여부와 상관없이 사용했던 리소스 객체의 close() 메소드를 호출해서 안전하게 리소스를 닫아준다.
} finally {
if(fis != null){
try{
fis.close(); // close 메소드 호출
} catch (IOException e) { }
}
}
AutoCloseable 인터페이스를 상속하면 close() 를 자동 호출한다.
public class FileInputStream implements AutoCloseable {
..
public void close() throws Exception {
System.out.println(file + "을 닫습니다. ");
}
}
6. 예외 떠넘기기
경우에 따라서는 메소를 호출한 곳으로 예외를 떠넘길 수도 있다.
이때 사용하는 키워드가 throws이다. throws 키워드는 메소드 선언부 끝에 작성되고, 그 뒤에 떠넘길 예외 클래스를 쉼표로 구분해서 나열해주면 된다.
리턴타입 메소드명(매개변수, ..) throws 예외클래스1, 예외클래스2, .. {
}
발생할 수 있는 예외의 종류별로 throws 뒤에 나열하는 것이 일반적이지만, 다음과 같이 throws Exception을호 모든 예외를 간단히 떠넘길 수도 있다.
리턴타입 메소드명(매개변수, ..) throws Exception{
}
7. 사용자 정의 예외와 예외 발생
자바 표준 API에는 존재하지 않는 특별한 예외를 정의해야 할 때 사용한다.
1. 사용자 정의 예외 클래스 선언
일반 예외로 선언할 경우 Exception을 상속하면 되고, 실행 예외로 선언할 경우에는 RuntimeException을 상속하면 된다.
public class XXXException extends [ Exception | RuntimeException ] {
public XXXException() {}
public XXXException(String message) { super(message); }
}
2. 예외 발생시키기
코드에서 예외를 발생시키는 방법은 다음과 같다.
throw new XXXException();
throw new XXXException("메시지");
예외 발생 코드를 가지고 있는 메소드는 대부분 자신을 호출한 곳에서 예외를 처리하도록 throws 키워드로 예외를 떠넘긴다.
public void method() throws XXXException {
throw new XXXException("메시지");
}
8. 예외 정보 얻기
try 블록에서 예외가 발생되면 예외 객체는 catch 블록의 매개변수에서 참조하게 되므로 매개 변수를 이용하면 예외 객체의 정보를 할 수 있다.
가장 많이 사용되는 메소드는 getMessage()와 printStackTrace()이다.
예외가 발생한 상세한 원인을 세분화하기 위해 예외 코드를 포함하기도 하는데, 예를 들어 데이터베이스에서 발생한 오류들은 예외 코드가 예외 메시지로 전달된다. 이와 같은 예외 메시지는 다음과 같이 catch 블록에서 getMessage() 메소드의 리턴값으로 얻을 수 있다.
} catch(Exception e) {
String message = e.getMessage();
}
printStackTrace()는 모든 예외 발생 코드를 추적해서 모두 콘솔에 출력한다.
어떤 예외가 어디에서 발생했는지 상세하게 출력해주기 때문에 프로그램을 테스트하면서 오류를 찾을 때 활용된다.
try {
} catch(예외클래스 e) {
// 예외가 가지고 있는 Message 얻기
String message = e.getMessage();
// 예외의 발생 경로를 추적
e.printStackTrace();
}
'Study in SSAFY > 이것이 자바다' 카테고리의 다른 글
[이것이 자바다] 12.6 멀티스레드 - 스레드 상태 제어 (0) | 2022.09.12 |
---|---|
[이것이 자바다] 12.5 멀티스레드 - 스레드 상태 (0) | 2022.09.12 |
[이것이 자바다] 12.4 멀티스레드 - 동기화 메소드와 동기화 블록 (0) | 2022.09.12 |
[이것이 자바다] 11. 기본 API 클래스(Math~Formatting) (0) | 2022.08.10 |
[이것이 자바다] 02. 변수와 타입 (0) | 2022.07.27 |