티스토리 뷰
Goal
- 오류와 예외 클래스에 대해 알아본다
- 예외 처리의 다양한 방식에 대해 알아본다
1. 오류란 무엇인가?
- 컴파일 오류 : 프로그램 코드 작성 중 발생하는 문법적 오류
- 실행 오류 : 실행 중인 프로그램이 의도 하지 않은 동작을 하거나(bug) 프로그램이 중지 되는 오류 (runtime error)
- 자바는 예외 처리를 통해여 프로그램의 비정상 종료를 막고 log를 남길 수 있음
2. 오류와 예외 클래스
- 시스템 오류 (error) : 가상 머신에서 발생, 프로그래머가 처리 할 수 없음. ex) 동적 메모리를 다 사용한 경우, stack over flow 등
- 예외 (Exception) : 프로그램에서 제어할 수 있는 오류. 읽으려는 파일이 없는 경우, 네트웍이나 소켓 연결 오류 등. 자바 프로그램에서는 예외에 대한 처리를 수행 함.
3. 예외 클래스
- 모든 예외 클래스의 최상위 클래스는 Exception 클래스
4. 예외 처리
4-1 try - catch - finally 문으로 예외 처리 하기
try{
// 예외가 발생할 수 있는 코드 부분
} catch (처리할 예외 타입 e) {
try블록 안에서 예외가 발생했을 때 수행되는 부분 (예외 내용 출력 등)
} finally {
예외 발생 여부와 상관 없이 항상 수행되는 부분
리소스를 정리하는 코드를 주로 씀
}
1) try - catch - finally 사용 예제
package exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("a.txt");
} catch (FileNotFoundException e) { //1) try에서 실행 한 코드가 FileNotFoundException에 해당하면
System.out.println(e); //2) 에러메세지 e를 출력한다.
// return;
} finally {
try { //finally 구문이 실행될 때도 exception이 발생할 수 있으므로 try - catch문을 통해 처리한다.
fis.close(); //리소스를 닫아준다.
System.out.println("finally");
} catch (Exception e) {
System.out.println(e);
}
}
System.out.println("end");
}
}
4-2 try - with - resources 문으로 예외 처리 하기
- 리소스를 자동으로 해체하도록 제공해주는 구문, finally를 사용하여 리소스를 해제할 때보다 코드의 가독성을 향상시킬 수 있음.
- 해당 리소스가 AutoCloseable을 구현한 경우 close()를 명시적으로 호출하지 않아도 try{} 블록에서 오픈된 리소스는 정상적인 경우나 예외가 발생한 경우 모두 자동으로 close()가 호출 됨
- 자바 7부터 제공 됨
- FileInputStream의 경우 AutoCloseable을 구현 하고 있음
1) try - with - resources 사용 예제
package exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TryWithResourse {
public static void main(String[] args) {
//close를 하지 않아도 AutoCloseable을 해준다.
try( FileInputStream fis = new FileInputStream("a.txt")) {
} catch (FileNotFoundException e) {
System.out.println(e);
e.printStackTrace();
} catch (IOException e) {
System.out.println(e);
}
}
}
2) AutoCloseable 인터페이스 사용하기
- AutoCloseable 인터페이스를 구현한 클래스를 만들고 close()가 잘 호출되는지 확인.
- AutoCloseable 구현
package exception;
public class AutoCloseObj implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("close()가 호출되었습니다");
}
}
- AutoCloseable을 구현한 클래스 사용
package exception;
public class AutoCloseTest {
public static void main(String[] args) {
try (AutoCloseObj obj = new AutoCloseObj()){
throw new Exception();
} catch (Exception e) {
}
}
}
5. 다양한 예외 처리
5-1 예외 처리 미루기
- throws를 사용하여 예외처리 미루기
- try{} 블록으로 예외를 처리 하지 않고, 메서드 선언부에 throws를 추가
- 예외가 발생한 메서드에서 예외 처리를 하지 않고 이 메서드를 호출한 곳에서 예외 처리를 한다는 의미
- main() 에서 throws를 사용하면 가상머신에서 처리 됨.
- throw : exception을 발생시키는 코드
- throws : exception을 미루는 코드, 메서드를 호출(사용)하는 쪽에서 에러를 처리하게 함.
package exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ThrowsException {
//throws 통해 예외 처리 미루기
public Class loadClass(String fileName, String className) throws FileNotFoundException, ClassNotFoundException {
FileInputStream fis = new FileInputStream(fileName);
Class c = Class.forName(className);
return c;
}
public static void main(String[] args) {
//메서드를 호출한 곳에서 try catch를 통해 예외를 처리
ThrowsException test = new ThrowsException();
try {
test.loadClass("b.txt", "java.lang.string");
} catch (FileNotFoundException e) {
System.out.println(e);
} catch (ClassNotFoundException e) {
System.out.println(e);
}
}
}
5-2 다중 예외 처리하기
- 하나의 try{} 블록에서 여러 예외가 발생하는 경우 catch{} 블록 한 곳에서 처리하거나 여러 catch{} 블록으로 나누어 처리 할 수 있음
- 가장 최상위 클래스인 Exception 클래스는 가장 마지막 블록에 위치해야함, 맨위나 중간에 위치하면, 미리 설정한 오류를 거치지 않고 Exception클래스가 해당 에러를 캐치함.
//multi blocks를 통해 예외를 한번에 처리
try {
test.loadClass("a.txt", "java.lang.String");
} catch (FileNotFoundException | ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("end");
ThrowsException test = new ThrowsException();
try {
test.loadClass("a.txt", "java.lang.String");
} catch (FileNotFoundException e) {
System.out.println(e);
} catch (ClassNotFoundException e) {
System.out.println(e);
/*
* 디폴트 exception : Exception이 최상위이기 때문에
* 모든 예외가 업캐스팅이 되고,
* 이미 정의한 예외 이외의 error가 발생할 경우를 대비함.
* 디폴트 exception은 맨 뒤에 처리해야 한다.
*/
} catch(Exception e) {
System.out.println(e);
}
System.out.println("end");
5-3 사용자 정의 예외
- JDK에서 제공되는 예외 클래스 외에 사용자가 필요에 의해 예외 클래스를 정의하여 사용
- 기존 JDK 클래스에서 상속받아 예외 클래스를 만듬
- throw 키워드로 예외를 발생시킴
1) Exception 클래스를 상속받아 Custome exception 정의
package exception;
public class IDFormatException extends Exception {
public IDFormatException(String message) { //String message : exception에 대한 메세지를 출력함.
super(message);
}
}
2) Custome한 exception을 사용한 예제
- setting한 UserID가 null이거나 8자 이상 20자 이하가 아닐 경우 에러가 발생하도록 custome exception 사용
- throw : exception을 발생시키는 코드
- throws : exception을 미루는 코드, 메서드를 호출(사용)하는 쪽에서 에러를 처리하게 함.
package exception;
public class IDFormatTest {
private String userID;
public String getUserID() {
return userID;
}
public void setUserID(String userID) throws IDFormatException {
if (userID == null) {
throw new IDFormatException("아이디는 null 일 수 없습니다");
}
else if (userID.length() < 8 || userID.length() > 20 ) {
throw new IDFormatException("아이디는 8자 이상 20자 이하로 쓰세요");
}
this.userID = userID;
}
public static void main(String[] args) {
IDFormatTest idTest = new IDFormatTest();
String myId = null;
//사용하는 쪽에서 exception처리
try {
idTest.setUserID(myId);
} catch (IDFormatException e) {
System.out.println(e);
}
myId = "123456";
try {
idTest.setUserID(myId);
} catch (IDFormatException e) {
System.out.println(e);
}
}
}
3) 출력 결과
'Java > Java 올인원 패키지' 카테고리의 다른 글
34. 직렬화 (Java) (0) | 2020.04.06 |
---|---|
31. 입출력 스트림 (Java) (0) | 2020.03.24 |
29. 스트림 (Java) (0) | 2020.03.23 |
28. 람다식 (Java) (0) | 2020.03.23 |
27. 내부 클래스 (Java) (0) | 2020.03.21 |
- 20201204
- 20200425
- 20200319
- chapter8
- 20200420
- 20200510
- 생활코딩리눅스
- 20200512
- 20200624
- 20200428
- 20200429
- 20200502
- 20200424
- 20200403
- 20200417
- chapter7
- 20200415
- 20200317
- 20200804
- likelion
- 20200423
- 20200421
- 20200406
- 20200413
- 20200330
- 백준
- 20200504
- 20200427
- 20200622
- 20200503
- Total
- Today
- Yesterday