< 에러 >
[ 종류 ]
시스템 에러 | 컴퓨터의 오작동으로 인해 발생하는 에러 |
컴파일 에러 | 프로그램 실행 전, 실행을 막는 소스코드상의 문법적인 문제로 발생하는 에러 |
런타임 에러 | 프로그램 실행 중 발생하는 에러 |
논리 에러 | 소스코드상 문법적인 문제가 없고 실행시 오류가 발생하지 않지만, 프로그램의 의도와 맞지 않는 실행결과가 나오는 에러 |
< 예외 (Exception) >
- 시스템에러를 제외한 나머지 컴파일, 런타임 논리에러와 같이 비교적 덜 심각한 에러
- 소스코드 수정으로 해결 가능한 에러. 특히, 런타임에러를 주로 예외로 다룸
uncheckedException | - 꼭 예외처리를 할 필요는 없는 예외 - 실행해야 예외가 발생하는지 알 수 있음 |
checkedException | - 문법적으로 반드시 예외처리를 해야하는 예외 - 실행 전, 예외처리를 하지 않았음을 알려줌 ex) 오류 문구 - Unhandled exception type IOException |
[ RuntimeException ] 세부 예외들을 자식클래스로 가지고 있음
- NullPointerException : 주소값 객체를 참조했을때 null이 들어있을 경우 발생하는 예외
- ArrayIndexOutOfBoundsException : 배열의 부적절한 인덱스로 접근할 때 발생하는 예외
- ClassCastException : 허용할 수 없는 형변환을 진행할 경우 발생하는 예외
- ArithmeticException : 나누기 연산시, 0으로 나누면 발생하는 예외
- NegativeArraySizeException : 배열 크기를 음수로 지정할 경우 발생하는 예외
- InputMismatchException : 사용자에게 입력 값을 받을때, 다른 자료형을 입력하는 경우 발생하는 예외
.... 그외 다수
< 예외처리 >
- 예외들이 발생했을 경우에 대비해서 처리하는 방법을 정의해두는 것
[ 방법 ]
1. try ~ catch문을 이용
- 문제 발생 시, 해당 구문을 출력 후 코드를 이어가게 함. 문제를 해결하는 것은 아님
- 문제가 발생한 구문에서 바로 catch문으로 이동함. 문제발생 이후 구문은 무시
- 다중 catch문 가능 : catch할 예외가 여러개일 경우 사용
- 에러들이 RuntimeException의 자식 클래스들이므로,
catch문에 RuntimeException을 사용하여 모든 오류 받기 가능(다형성 이용)
[ 표현법 ]
try {
예외가 발생할법한 구문
} catch (발생할 예외 클래스이름 변수명) { → 변수명 'e' 사용
해당 예외가 발생했을 때 실행할 구문
} finally {
예외가 발생하더라도 반드시 실행할 구문
}
public void method1() {
// 사용자에게 두 개의 정수값을 입력받아서 나눗셈 결과 출력
Scanner sc = new Scanner(System.in);
System.out.print("첫번째 정수 > ");
int num1 = sc.nextInt();
System.out.print("두번째 정수 > ");
int num2 = sc.nextInt();
// 예외처리 구문
try {
System.out.println("나눗셈 결과 : " + (num1 / num2));
// 문제가 난 라인에서 catch문으로 이동함. ↓아래 구문은 출력하지 않음. 무시하고 catch로
System.out.println("문제 발생 없음");
} catch (ArithmeticException e) { // 매개변수명으로 주로 e 사용
System.out.println("0 안돼. 돌아가."); // 해당 오류 발생시 출력할 구문
e.printStackTrace(); // 오류를 추적할 수 있는 메소드(현재 발생한 오류의 정보를 출력)
}
System.out.println("종료합니다.");
}
- printStackTrace() : 오류를 추적할 수 있는 메소드
현재 오류가 발생한 정보를 볼 수 있고, 어디서 에러가 났는지 나열
개발, 테스트 단계에서만 사용. 사용자에게 보여지지않도록 주의 (취약점 노출)
[ 다중 catch문 ]
public void method3() {
// 사용자로부터 배열의 크기를 입력받아서 배열 만들기, 100번째 인덱스값 출력
Scanner sc = new Scanner(System.in);
System.out.print("배열의 크기 : ");
try { // 3가지 예외 발생 가능
int size = sc.nextInt(); // 1. InputMismatchException
int[] arr = new int[size]; // 2. NegativeArraySizeException
System.out.println(arr[100]); // 3. ArrayIndexOutOfBoundsException
} catch(InputMismatchException e) {
System.out.println("정수를 입력해주세요.");
} catch(NegativeArraySizeException e) {
System.out.println("양수를 입력해주세요.");
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("100칸 배열이 없습니다.");
} catch(RuntimeException e) { // 부모클래스인 RuntimeException으로 자식클래스 예외 모두 받음
System.out.println("배열 오류 발생");
}
// 다중 catch문 작성시, 범위가 작은 자식타입의 예외클래스부터 먼저 기술해야 함
// (RuntimeException을 먼저 적으면 아래 catch문으로 갈 수 없음)
System.out.println("프로그램을 종료합니다.");
}
[ try ~ catch ~ finally ]
public void fileSave() {
// FileWriter : 파일로 데이터를 2Byte 단위로 출력하는 스트림
FileWriter fw = null; // try구문과 분리
try {
// 1. 객체 생성 => 파일과 연결된 통로 생성
fw = new FileWriter("b_char.txt"); // 예외처리 : IOException
// 2. 파일에 쓰기 => write()
fw.write("출력하는 중\n");
fw.write("B");
char[] arr = {'a', 'b', 'c', 'd'};
fw.write(arr); // 오버로딩 적용
} catch(IOException e) {
e.printStackTrace();
} finally { // try에서 오류가 발생하더라도 반드시 실행할 구문 작성
// 3. 자원반납 => close() 통로 닫기
try {
fw.close(); // 예외처리 : IOException
// 자원반납을 해서 통로를 닫지 않으면 데이터가 입력되지 않음
} catch(IOException e) {
e.printStackTrace();
}
}
}
2. throws를 이용 (떠넘기기)
- 문제가 발생한 메소드가 아닌, 메소드를 호출한 곳에 예외를 떠넘겨서(위임해서) 처리
[ 사용 이유 ] 오류를 기록하는 로그에서 해당 오류를 넘겨받을 수 있게 하기 위해 사용
public void method2() throws IOException { // 클래스 옆에 throws 작성
System.out.println("아무 문자열이나 입력해주세요 : ");
// Scanner와 같이 키보드로 값을 입력받을 수 있는 객체(문자열로만 가능)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine(); // 여기서 발생하는 예외처리를 메소드를 호출한 곳에서 해결하게함
// 예외처리 하지 않으면 오류 출력(Unhandled exception type IOException)
System.out.println("문자열 길이 : " + str.length());
}
public void method1() {
try {
method2(); // '문제가 발생한 메소드를 호출한 곳'에서 예외처리 해야함
} catch(IOException e) {
System.out.println("예외 발생");
}
}
'개발 > Java' 카테고리의 다른 글
[Java] 자바 - 데이터 입출력 / 스트림(Stream) / 바이트 스트림 / 문자 스트림 (0) | 2022.09.21 |
---|---|
[Java] 자바 - 파일 생성 ( File클래스 ) (1) | 2022.09.21 |
[Java] 자바 - 인터페이스 ( 예약어 implements ) (0) | 2022.09.20 |
[Java] 자바 - 추상 메소드 / 추상 클래스 ( 예약어 abstract ) (0) | 2022.09.20 |
[Java] 자바 - 다형성(Polymorphism) / 업캐스팅(Upcasting) / 다운캐스팅(Downcasting) / 동적바인딩 / instanceof 연산자 (0) | 2022.09.19 |