Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- jpa - 객체지향 쿼리 언어
- 자바의 정석 기초편 ch14
- 자바의 정석 기초편 ch2
- 스프링 db2 - 데이터 접근 기술
- 자바의 정석 기초편 ch3
- 자바의 정석 기초편 ch11
- 자바의 정석 기초편 ch12
- @Aspect
- 스프링 mvc1 - 서블릿
- 스프링 db1 - 스프링과 문제 해결
- 스프링 입문(무료)
- 자바의 정석 기초편 ch1
- 타임리프 - 기본기능
- 2024 정보처리기사 수제비 실기
- 스프링 고급 - 스프링 aop
- 자바의 정석 기초편 ch5
- 자바의 정석 기초편 ch6
- 코드로 시작하는 자바 첫걸음
- 스프링 mvc2 - 로그인 처리
- 자바의 정석 기초편 ch7
- 자바의 정석 기초편 ch13
- 2024 정보처리기사 시나공 필기
- 스프링 mvc1 - 스프링 mvc
- 자바의 정석 기초편 ch8
- 자바의 정석 기초편 ch9
- jpa 활용2 - api 개발 고급
- 게시글 목록 api
- 스프링 mvc2 - 검증
- 자바의 정석 기초편 ch4
- 스프링 mvc2 - 타임리프
Archives
- Today
- Total
나구리의 개발공부기록
자바의 정석 기초편 ch8 - 11 ~ 18[예외선언하기, finally블럭, 사용자정의예외만들기, 예외 되 던지기, 연결된 예외] 본문
유튜브 공부/JAVA의 정석 기초편(유튜브)
자바의 정석 기초편 ch8 - 11 ~ 18[예외선언하기, finally블럭, 사용자정의예외만들기, 예외 되 던지기, 연결된 예외]
소소한나구리 2023. 12. 5. 10:021) 예외를 처리하는 방법
(1) try-catch문
- 직접 처리하는 방법
(2) 메서드에 예외 선언하기
- 예외를 호출하는 쪽에 알리는 것으로 예외를 떠넘긴다고도 표현함
- 체크드 예외와 언체크드 예외를 모두 적어도 되지만 보통 체크드 예외만 적는 것이 정석
// 메서드의 예외 선언
// - throws 이후부터 예외1,2 ~ N까지의 예외의 상황이 발생할 수 있음
void method() throws Exception1, Exception2, ... ExceptionN {
// 메서드 내용
}
// 메서드의 예외 선언
// - 모든 예외의 최고조상인 Exception으로 모든 예외가 발생할 수 있음
// Exception은 모든 예외의 최고 조상이므로 위의 3가지의 예외를 선언한 것보다 예외를 더 많이 선언한 것이 됨.
void method() throws Exception {
// 메서드 내용
}
(3) 예제
- 위 예제는 예외가 발생하면 처리하지 않고 예외가 발생된 메서드에 끝부분에 throw를 작성하여 예외를 그대로 밖으로 던짐
- 아래 예제는 예외가 발생하는 부분에 대해 직접 try - catch로 예외를 처리
// 예외를 호출한 곳에서 처리하도록 throw로 던지는 예제
import java.io.*;
class ex8_10 {
public static void main(String[] args) {
try {
File f = createFile(""); // 예외 발생
System.out.println( f.getName()+"파일이 성공적으로 생성되었습니다.");
} catch (Exception e) {
System.out.println(e.getMessage()+" 다시 입력해 주시기 바랍니다.");
}
} // main메서드의 끝
// 예외가 발생하면 밖으로 던지기 위해 메서드에 throws Exception이 선언됨
static File createFile(String fileName) throws Exception {
if (fileName==null || fileName.equals(""))
throw new Exception("파일이름이 유효하지 않습니다.");
File f = new File(fileName); // File클래스의 객체를 만듦
f.createNewFile(); // createNewFile메서드를 이용해서 실제 파일을 생성
return f; // 생성된 객체의 참조를 반환
} // createFile메서드의 끝
} // 클래스의 끝
// 예외를 try - catch로 직접 처리한 예제
import java.io.*;
class ex8_10 {
public static void main(String[] args) {
File f = createFile(""); // 예외 발생
System.out.println( f.getName()+"파일이 성공적으로 생성되었습니다.");
} // main메서드의 끝
static File createFile(String fileName) {
try {
if (fileName==null || fileName.equals(""))
throw new Exception("파일이름이 유효하지 않습니다.");
} catch (Exception e) {
fileName = "이름없음.txt";
}
File f = new File(fileName); // File클래스의 객체를 만듦
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
return f; // 생성된 객체의 참조를 반환한다.
} // createFile메서드의 끝
} // 클래스의 끝
(4) 은폐
- 발생된 예외를 감춤
- catch문으로 발생된 예외를 잡지만 빈블럭으로 둠으로써 예외를 잡고 그에 따라 실행되는 코드가 없이 그냥 정상흐름으로 넘어감
- 거의 사용하지 않지만 빅데이터를 사용할 때 일부 문제있는 데이터를 버리는 용도로 사용하기도 함
2) Finally블럭
- 예외 발생여부와 관계없이 프로그램 로직상에서 꼭 수행되어야 하는 코드를 작성
- try블럭 안에 return문이 있어서 try블럭을 벗어나도 finally블럭은 실행 됨, 즉 무조건 실행된다고 보면됨
- try-catch문 작성시 발생되는 코드의 중복을 제거하기 위해 만들어졌으며 catch문 다음에 선언함(가장 마지막에 선언)
try {
// 예외가 발생할 가능성이 있는 문장 작성
} catch (Exception1 e1) {
// 예외 처리를 위한 문장 작성
} finally {
// 예외의 발생여부에 관계없이 항상 수행되어야하는 문장들을 작성
// finally블럭은 try-catch문의 맨 마지막에 위치
}
// try-catch의 코드 중복 발생
try {
startInstall();
copyFile();
deleteTempFiles(); // 임시파일 삭제
} catch {
e.printStackTrace();
deleteTempFiles(); // 임시파일 삭제
}
// 임시파일을 삭제하는 코드가 중복이되어 finally 문으로 중복을 제거
try {
startInstall();
copyFile();
} catch {
e.printStackTrace();
} finally {
deleteTempFiles(); // 임시파일 삭제
}
3) 사용자 정의 예외 만들기
- 사용자가 직접 예외 클래스를 정의하여 사용할 수 있으며 상속을 통해서 작성함
- 조상은 Exception / RuntimeException 예외 중에서 선택하여 예외를 생성할 수 있음,
- 일반적으로 선택처리가 가능한 RuntimeException으로 예외를 만드는 경우가 많고 꼭 필요한 경우에는 Exception으로도 할 수 있음
class MyException extends Exception { // 필수 처리 예외(try - catch문이 필수)
MyException(String msg) { // 문자열을 매개변수로 받는 생성자 필수
super(msg); // 조상인 Exception클래스의 생성자를 호출 - 보통 넣어줌
}
}
4) 예외 되던지기
- 예외를 처리한 후에 다시 예외를 발생시키는 것
- try-catch로 예외를 처리(전부 처리하거나 일부)했지만 메서드에 throws로 처리한 예외(혹은 아직 처리하지 못한 예외를)를 던져서 호출한쪽에서 예외를 처리하도록 함
- 호출한 메서드와 호출된 메서드 양쪽에서 각각 2번 예외를 처리를 하도록 코드를 설계하는 것
- 이러한 상황이 거의 발생하지 않을 수 있지만 실무에서는 여러가지 상황을 마주할 수 있으므로 알고있으면 좋음
class Ex8_12 {
public static void main(String[] args) {
try {
method1(); // 메서드 호출
} catch (Exception e) { // 예외 처리2(예외선언 처리)
System.out.println("main메서드에서 예외가 처리되었습니다.");
}
} // main메서드의 끝
static void method1() throws Exception { // 예외 선언
try {
throw new Exception(); // 예외 발생
} catch (Exception e) { // 예외 처리1(직접 처리)
System.out.println("method1메서드에서 예외가 처리되었습니다.");
throw e; // 다시 예외를 발생
}
} // method1메서드의 끝
}
5) 연결된 예외(chained exception)
- 한 예외가 다른 예외를 발생시키거나 하나의 예외안에 또다른 예외를 포함
- 예외A가 예외B를 발생시키면 A는 B의 원인예외(cause exception)가 됨
(1) Throwable 클래스의 일부
- Throwable initCause(Throwable cause) : 지정한 예외를 원인 예외로 등록하는 메서드가 정의 되어있음
- Throwable getCause() : 원인 예외를 반환하는 메서드가 정의 되어있음
// 예외 안에 또다른 예외를 포함
public class Throwable implements Serializable {
...
private Throwable cause = this; // 객체 자신을 원인 예외로 등록
...
public synchronized Throwable initCause(Throwable cause) {
...
this.cause = cause; // cause를 원인 예외로 등록
return this;
}
...
}
6) 연결된 예외를 사용하는 이유
(1) 여러 예외를 하나로 묶어서 다루기 위해
- 코드의 중복을 일부 제거할 수 있음
- 예외가 발생한 원인은 SpaceException 예외 이지만 catch문에서 새로운 예외를 하나 생성하여 해당 예외의 원인예외로 SpaceException 예외를 등록하고 새로 생성된 예외를 던짐
- 메서드에 throws문을 작성하여 원인예외를 담아 새로 작성한 예외를 밖으로 던짐
- 예외 정보나 예외 메세지를 출력 시 예외의 이유를 세부적으로 알 수 있음
// 여러 예외가 발생 시 코드 중복 발생
try {
install();
} catch(SpaceException e) {
e.printStackTrace();
} catch(MemoryException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
// install()를 정의하여 SpaceException,MemoryException을 한개의 InstallException으로 변경
void install() throws InstallException { // 예외 B로 예외를 밖으로 던짐
try {
startInstall(); // SpaceException발생, 예외 A라고 가정
copyFiles();
} catch (SpaceException e) {
InstallException ie = new InstallException("설치중 예외발생"); // 예외 B라고 가정
ie.initCause(e); // InstallException의 원인예외를 SpaceException으로 지정
throw ie; // InstallException을 발생, 예외 B를 발생
} catch (MemoryException me) {
...
// 실제 발생한 예외는 SpaceException 이지만 InstallException 안에 포함시켜서 밖으로 던짐
// 코드의 중복을 일부 제거함
try {
install();
} catch(InstallException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
(2) checked예외를 unchecked예외로 변경하려 할 때
- try - catch를 쓰지 않아도되는 필수 처리 예외가 존재할 경우 사용함
- 조상을 바뀌어서 언체크드 예외로 변경할 수도 있지만, 해당 예외가 여러곳에 사용 중이라면 상속계층도를 바꾸는 것이 어렵기 때문에 특정 시점에 연결된 예외를 써서 런타임 예외로 변경할 수 있음
// SpaceException을 RuntimeException으로 변경하고자 할 때 조상을 바꿔 주면 되지만
// SpaceException이 여러 곳에 쓰이고 있다면 상속계층도를 변경하는 것은 어려움 -> 연결된 예외 사용
class SpaceException extends Exception {
SpaceException(String msg) {
super(msg);
}
}
// 둘다 checked일때 try-catch를 선언하지 않으면 둘다 밖으로 던져야 함
static void startInstall() throws SpaceException, MemoryException {
if(!enoughSpace())
throw new SpaceException("설치할 공간이 부족합니다.");
if(!enoughMemory())
throw new MemoryException("메모리가 부족합니다.");
}
// MemoryException을 런타임 예외로 변경하여 메서드에 throws를 작성 하지 않아도됨
static void startInstall() throws SpaceException {
if(!enoughSpace())
throw new SpaceException("설치할 공간이 부족합니다.");
if(!enoughMemory())
// MemoryException을 RuntimeException으로 변경하는 방법
throw new RuntimeException(new MemoryException("메모리가 부족합니다."));
}
** 출처 : 남궁성의 정석코딩_자바의정석_기초편 유튜브 강의