코딩 기록들
[Java Programming] 10.2 예외처리 (try~catch, finally, throw) 본문
자바의 예외 종류
Throwable (예외 최상위 클래스)
|
Exception (try~catch : 필수) -> 을 상속받은 예외들은 if로 처리할 수 없음
(컴파일 exception : 컴파일 할 때 예외 발생 여부 확인)
-> 코드 쓸 때 예외가 반드시 처리 돼야함
(자바가 예외를 처리하는 방법을 완전히 분리시켜놨기 때문에, Exception만 상속받는 경우는 try~catch를 반드시 써주기)
ex) IOE Exception / ClassNotFound Exception
|
RuntimeException (try~catch : 옵션) -> 을 상속받은 예외들은 if로 처리할 수 있음
(= 실행중 발생하는 예외)
-> 실행 중 예외 '회피' 해줘야됨
ex) NullPointerException / ArrayIndexOutOfBoundsException / IndexOutOfBoundsException / NumberFormatException
try~catch~finally
- if 로 예외처리 할 수 없거나, 애매할경우 : try~catch~finally 사용
- 예외가 발생 할 확률이 있는 코드를 try 안에 넣어줌
- try에 들어가는 코드는 짧을수록 좋다
- try의 역할 : 예외가 발생할지 모르겠지만 일단 실행을 해봐!
-> 예외발생? : JVM으로 예외 보내지 않고 그 예외를 내가 내부적으로 처리 -> catch 실행
-> catch의 소괄호 안 : try코드가 예외를 발생시키는 예외클래스를 똑같이 작성해줌
(catch : 예외가 발생되었을때 만 실행됨)
- finally : 예외가 발생했던, 하지않았던 무조건 실행됨 (DB 자바와 함께 연동할때 쓰일것)
try {
// ▼ NumberFormatException 발생
int number = Integer.parseInt("ABC"); // 문자를 숫자로 바꾸므로 NumberFormatException 발생
System.out.println(number); // 이 코드는 실행되지 않습니다.
}
// ▼ NumberFormatException이 발생했을 때 catch가 실행됨
catch ( NumberFormatException e ) {
// try에서 예외가 발생하면 catch 실행
System.out.println("에러가 발생했습니다. " + e.getMessage()); //e : 예외의 인스턴스
e.printStackTrace(); // 에러내용 모두 출력
}
finally { // 실무에서는 finally까지는 잘 쓰지 않음
// 예외 발생 여부와 관계없이 무조건 실행됩니다.
System.out.println("처리가 완료됐습니다.");
}
- try-catch문 너무 많이쓰면 수행속도에 영향을 미침(느려짐)
예제) SomeAClass의 패키지와 클래스이름을 가지고와서 그것의 인스턴스를 만들어라
1. 클래스 동적로딩
public static void main(String[] args) {
Class.forName("SomeAClass");
}
-> Unhandled exception type ClassNotFoundException 발생 (ClassNotFoundException 타입 예외 에러를 처리하지 않았다는 뜻) -> 이를위해 try~catcth 문 사용 ???
public static void main(String[] args) {
try {
Class.forName("SomeAClass");
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
}
하나의 try에서 여러개의 Exception 발생 -> catch 여러번 사용
try { //try는 반드시 catch가 따라옴. 혼자있을수 없음!
Class.forName("exception_handling.IfArrayIndexOutOfBoundsException");
Files.readAllLines(imageFile.toPath());
}
//catch를 1개만 쓰는 방법 (쓰고봤더니 에러를 같은 방식으로 처리를 할 경우 아래와 같이 씀)
catch(ClassNotFoundException | IOException cnfe){ // 보통 여러개의 예외처리하는 이런상황에서는 cnfe이 아닌, 'ex' 라고 씀
String message = cnfe.getMessage();
System.out.println(message);
}
package exception_handling;
import java.io.File;
import java.nio.file.Files;
import java.io.IOException;
public class TryCatchExam {
public static void main(String[] args) {
// 시스템 드라이브에서 특정경로에 있는 파일 또는 폴더를 읽어온다.
File imageFile = new File("c:\\sdfsdfsdf"); //생성자 뭐가있는지 궁금할땐 괄호쓰지않고 생성자 이름만쓰고 ctrl space
try {
Files.readAllLines(imageFile.toPath()); // 파일에 있는 내용들을 다 읽어와서 문자열타입으로 바꿔라
}
catch(IOException ioe) {
String message = ioe.getMessage(); // catch 에 작성한 IOException와 실제 예외(java.nio.file.NoSuchFileException)는 다를 수 있다
System.out.println(message); // java.nio.file.NoSuchFileException -> IOException을 상속받는 클래스 FileSystemException
//아주 상세한 예외 목록(호출 스택)
ioe.printStackTrace();
}
// Class.forName //-> 빠르게 에러종류 찾는방법 : ctrl + space
try { //try는 반드시 catch가 따라옴. 혼자있을수 없음!
Class.forName("exception_handling.IfArrayIndexOutOfBoundsException");
Files.readAllLines(imageFile.toPath());
}
// catch(ClassNotFoundException cnfe){ //cnfe : 대문자만 골라서 적어주기
// String message = cnfe.getMessage();
// System.out.println(message);
//
// //아주 상세한 예외 목록(호출 스택)
// cnfe.printStackTrace();
// }
// catch(IOException ioe) {
// String message = ioe.getMessage();
// System.out.println(message);
//
// //아주 상세한 예외 목록(호출 스택)
// ioe.printStackTrace();
// }
//catch를 1개만 쓰는 방법 (쓰고봤더니 에러를 같은 방식으로 처리를 할 경우 아래와 같이 씀)
catch(ClassNotFoundException | IOException ex){
String message = ex.getMessage();
System.out.println(message);
//아주 상세한 예외 목록(호출 스택)
ex.printStackTrace();
}
}
}
catch블록 안에 써야하는 예외 종류 찾는 방법
1. ctrl + 단어(forName)클릭해서 확인
2. class.forName 치고 ctrl + space 해서 확인
error : jvm이 자체적으로 발생시키는 버그 (계속 같은에러 발생하면 자바 지우고 다시설치 해야됨)
exception : 우리가 try~catch, if 등으로 처리 가능
throw
- 예외를 발생시킴, 예외가 던져짐 (예외가 발생한 역순으로, 예외발생코드 위에서부터 아래로, 쿼리스택의 역순으로 예외를 던짐. 마지막에는 jvm으로 던져짐)
- 메소드 정의할 때 throws + 던지는 예외명 반드시 작성
- Exception type이 던져질때는 throw가 필수! (나머지는 throw 필수 아님)
Exception in tread "main"~ : 감싸두었던 예외
실제에러 : caused by~ 라인부터
- 일반적인 케이스에서는 finally 쓰지 않음 -> file, db에서 많이 사용함
실무에서 자주 사용하는 런타임 예외 처리 방법 예제
public class TryCatchExam {
//Exception type이 던져질때는 throw가 필수!!!
public static int convertToInt(String str) throws Exception {
try {
int number = Integer.parseInt(str);
return number;
}
catch(NumberFormatException nfe) {
//Exception exception = new Exception( str + "는 숫자로 변환할 수 없습니다." );
// Exception대신 RuntimeException으로 작성하면, Exception와 다르게 에러가 나오지 않음 : 예외를 변환시켜 던졌기 때문
Exception exception = new Exception(
str + "는 숫자로 변환할 수 없습니다.", nfe);
//,nfe : NumberformatException을 RuntimeException으로 감싸서 예외를 던진것
//throw : 예외를 발생시킴 (예외가 던져짐, jvm쪽으로. 즉, 호출한 메인코드로 던짐)
throw exception; // 즉시 예외를 던지고 메소드를 종료시킨다. throw 아래 다른 코드를 작성해도 실행안됨(dead code)
}
// throw를 하던말던, return을 하던말던 finally문은 언제나 반드시 실행 됨 (실제론, thorw 하기전에 잠깐멈추고 finally하고 throw 함)
finally {
System.out.println("변환이 완료되었습니다.");
}
}
public static void main(String[] args) {
try {
int num = convertToInt("AAA"); //exception타입의 예외를 받으므로 반드시 try~catch문 작성해줘야됨(안쓰면 컴파일자체가 안됨)
}
catch(Exception ex) {
System.out.println(ex.getMessage()); //"AAA는 숫자로 변환할 수 없습니다."
}
}
}
* 나를 호출하는 얘에게 예외위임(try-catch)하는 방법은 지양할것 *
public static List<String> readFile(File path) throws IOException {
return Files.readAllLines(path.toPath()); //File을 toPath로 변환시켜 진행 -> 이게 던지는 예외 : IOException
}
'Java' 카테고리의 다른 글
[Java Programming] 11.1 제네릭 (2) | 2024.01.31 |
---|---|
[Java Programming] 10.3 사용자 예외 발생시키기 (1) | 2024.01.30 |
[Java Programming] 10.1 예외처리 (0) | 2024.01.30 |
[Java Programming] 9.2 익명 클래스 (0) | 2024.01.29 |
[Java Programming] 9.1 추상화, 인터페이스 (1) | 2024.01.29 |