> 예외처리 exception handling
예외 excption
1. 컴파일러 체크 예외 (checked exception)
- 컴파일 과정에서 예외처리 코드 검사, 예외 처리 코드가 없다면 컴파일 오류
2. 실행 예외 (runtime exception, unchecked exception)
- 컴파일 과정에서 예외처리 코드를 검사하지 않는 예외
예외처리 exception handling
에러에 대한 처리
프로그램에서 문제가 될 만한 부분을 예상하여 사전에 '문제가 발생하면 이렇게 처리하라' 라고 프로그래밍 하는 것
예외 발생 시 문제가 발생한 부분의 정보 출력, 프로그램 종료
대표적인 실행 예외 종류
1. NullPointerException - 객체 참조가 없는 상태, null 값을 갖는 참조 변수로 객체 접근 연산자인 dot(.)을 사용했을 때 발생
2. ArrayIndexOutOfBoundsException - 배열의 인덱스 범위를 초과할 경우 발생
3. NumberFormatException - 문자열 데이터를 숫자로 변경하는 경우 발생
4. ClassCastException - 부모클래스-자식 클래스 / 구현클래스-인터페이스 관계가 아니면 다른 클래스로 형 변환 불가
예외처리방법1. try~ catch~ (finally)
try 블록 - 예외 발생 가능성이 있는 코드 작성
catch 블록 - try 블록에서 예외 발생 시 실행할 예외 처리 코드 작성
try 블록이 예외 발생 없이 정상 실행되면 catch 블록 실행 안됨
소괄호( ) 안에는 해당 예외를 처리할 수 있는 예외 클래스 타입이 선언됨 (Exception은 모든 예외를 처리)
finally 블록 - 예외 발생 여부와 무관하게 항상 실행할 내용 작성
public static void main(String[] args) {
int[] arr = {3, 6, 9}; //인덱스 0~2
try {
System.out.println(arr[3]); //Runtime Exception - ArrayIndexOutOfBoundsException
} catch(Exception a) {
System.out.pirntln("배열 인덱스 범위 벗어남");
} finally {
System.out.println("예외일까 아닐까?");
}
//배열 인덱스 범위 벗어남
//예외일까 아닐까?
다중 catch
try 블록에서 여러가지 예외가 발생하는 경우 다중 catch 블록을 작성하여 예외들을 처리
catch 블록은 위에서부터 차례대로 검색되므로, 하위 예외 클래스의 catch 블록이 상위 예외 클래스의 catch 블록보다 위에 위치해야 함
(상위 예외 클래스의 catch블록이 위에 있으면 하위 예외 클래스의 catch 블록은 실행되지 않기 때문)
동일하게 처리할 예외는 catch() 소괄호 안에서 "|"로 연결 (단, 이 때 두 예외가 상속관계이면 안됨)
public static void main(String[] args) {
try {
String data1 = args[0]; //run-run configurations-arguments에 입력한 값이 차례대로 배열에 저장됨
String data2 = args[1];
int var1 = Integer.parseInt(data1); //문자열을 정수형으로 변환
int var2 = Integer.parseInt(data2);
System.out.println(var1 + var2);
String str = null; //문자열 선언 후 null값으로 초기화
str.chatAt(0); //String으로 저장된 문자열 중 한글자만 char형으로 변환(소괄호 안 인덱스)
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값을 2개 띄어쓰기 형태로 전달하세요.");
} catch(NumberFormatException e) {
System.out.println("실행 매개값을 숫자로 전달하세요.");
} catch(Exception e) {
System.out.println("기타 예외입니다.");
} //상위 예외 클래스인 Exception이 제일 아래 위치
}
* 예외 처리 클래스의 상속 관계
Exception 클래스가 모든 예외를 처리할 수 있는 이유: Exception이 다른 모든 예외클래스들의 부모클래스이므로
Error 클래스를 상속하는 클래스들의 예외 상황은 시스템 오류 수준의 예외 상황, 프로그램에서 처리할 수준의 예외가 아님 (심각한 에러)
예외처리방법2. throws
메소드/생성자선언 throws 예외 클래스명 { }
예외처리를 직접 수행하지 않고 메소드나 생성자를 호출한 곳으로 예외를 떠넘기는 코드
메소드나 생성자는 여러 곳에서 쓰이므로 예외처리를 각 쓰임에 맞게 하기위해 throw를 사용해 떠넘김
throws 키워드가 붙은 메소드는 반드시 ≪try 블록 내부에서 호출되어 → catch 블록에서 예외 처리≫
main도 throws를 사용할 수 있음
public class ThrowsExam {
public static String[] arr = {"가", "나", "다"}; //배열arr, 인덱스0~2
public static void method1(int a) throws Exception { //메소드(반환없음,매개변수있음) - 예외떠넘기기throws
System.out.println(arr[a]);
}
public static void main(String[] args) { //메인메소드
try {
method1(3); //메소드호출 - 매개변수가 3이므로 배열의 범위 벗어남 -> 예외
} catch (Exception e) {
System.out.println("배열의 참조범위를 벗어남");
}
}
}
* 예외 강제 발생 시키기 throw
throw new 예외클래스
사용자가 직접 선언한 예외 클래스 or 자바가 제공하는 예외 API에서 - 예외를 강제로 발생시킴
예외를 강제 발생시키며 메소드 강제 종료 → 예외 떠넘기기(throws)구문으로 예외를 처리함
public static int calSum(int n) throws Exception { //메소드 + 예외떠넘기기throws
if(n <= 0) {
throw new Exception("매개값을 양수로 전달하세요"); //예외 강제 발생
}
int sum = 0;
for(int i = 1; i <= n; i++) {
sum += 1;
}
return sum;
}
public static void main(String[] args) {
try {
int a = calSum(-2);
} catch(Exception e) { //예외처리(throws로 넘겨받았으므로 반드시 처리)
System.out.println("양수를 입력하세요");
}
}
* 사용자 정의 예외
자바 표준 API에서 제공하는 예외 클래스만으로 모든 예외를 표현하기 어려움
개발자가 만든 어플리케이션에서 자체적으로 생기는 예외는 직접 예외 클래스를 정의해야 함
사용자 정의 예외 클래스는 Exception 클래스를 상속하여 사용, 이름은 Exception으로 끝나는 것이 좋음
일반적으로 기본 생성자와 예외 메시지를 받는 생성자를 만듦
public class MyException extends Exception { //Exception클래스 상속받음
public MyException() { //기본생성자
}
public MyException(String message) { //예외메시지를 받는 생성자
super(message);
}
}
'course 2021 > JAVA' 카테고리의 다른 글
day19 - API(2) generic, collection (0) | 2021.09.22 |
---|---|
day18 - API(1) java.lang, java.util (0) | 2021.09.15 |
day16 - interface (0) | 2021.09.08 |
day15 - final, abstract (0) | 2021.09.08 |
day14 - static (0) | 2021.09.07 |