일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 명령어
- Test 룸북 사용하기
- 다른사람 프로젝트 수정전 가져야할 자세
- 함수 인자값 id
- 시퀀스 조회
- 순서 보장
- 개발시작전 자세
- 타임리프
- linux
- 추천 사이트
- 타임리프와 스프링
- BindingResult
- 리눅스
- 스프링부트
- 룸북
- 자바스크립트 인라인
- StringUtils.hasText
- it
- 설정
- Intellij
- 프로젝트 클린
- JSON
- select
- #{..}
- 비밀번호 변경 명령어
- js
- cmd
- Java
- 하모니카 OS 5
- 추천 프로그램
- Today
- Total
웹개발 블로그
💥예외처리란? 사용할때 주의해야할 점? 본문
참고: https://www.youtube.com/watch?v=UkLceQi475o
오늘의 주제
과연 좋은 방법인가? 정확한 에러를 찾기가 오히려 힘들어서 오히려 안 쓰게 났다.
만약 그럼에도 try-catch문을 써야한다면? 예시를 들어보자.
예외 발생
- 예외가 발생되면 해당 예외로 정의되어 있는 Exception 객체 생성
- 예외 객체가 생성되면 JVM은 프로그램을 종료
예외 사용
- 개발자가 놓칠 수 있는 부분에 대해 예외 객체를 자동 생성하도록 함
- 클래스로 정의된 예외가 발생되므로 개발자가 조절 가능
- 개발자는 해당 예외가 발생되면은 어떻게 할 것인지를 처리하면 됨.
👀 나는 지금 달리기 중이다... 도착지에 도착하기 전에 어떤 변수를 마주칠지 모른다!!
상황1. 중간에 구덩이 빠지면?
상황2. 번개가 치면은? ..ETC
1. 컴파일 오류
자바 같은 컴파일 언어들은
즉, 실행되기 전에 기계에게 더 친숙한 언어로
번역, 컴파일된 어들은 문법 오류는 컴파일 과정에서 차단하기에 실행과정에서 오류가 나지 않는다.
2. 런타임 오류
프로그래머의 논리적 결함으로 인해 발생하는 걸 '논리 오류'라 부른다. - 실수~
Exception
1. Exception
- 예외처리 구문이 반드시 필요한 예외 ( try ~ catch 또는 throws)
- throws를 사용하면 또 다른 구문에서 처리해야한다.
- 컴파일 시 예외 처리 구문 작성 여부를 확인
- EX) 칼을 사용하기 전에는 무조건 다치지 않게끔하겠다
2. RuntimeException - 중요도가 낮을 때
- 예외처리 구문이 반드시 필요하지는 않음.
- 실행중 예외가 발생되면 예외처리 구문을 찾아서 실행
- EX) 길가다가 무조건 넘어지지는 않겠지? 또 넘어졌다고 치명상을 입지는 않는다!
ㄴ 반드시 컴파일할때 TRY-CATCH를 사용하지 않아도 됨.
ㄴ throw new 예외클래스(); //예외발생
ㄴ 예외클래스에서는 try-catch를 작성해두어 비정상적으로 종료되는 것을 막을 수 있다.
예외처리
try-catch-finally
//이전 동작
try{
//시도해 볼 동작
}catch(Exception e) {
//오류 발생 시
// catch는 여러개 생성 가능
// -> 단 최상위 Exception은 아래에 두자
// 💥예외객체가 생성되면 매치되는 catch()를 호출한다고 이해하자.
}finally{
//💥용도로는 주로 '자원 해제'
// 무조건 사용 안해도 됨.
//성공 시 또는 오류 발생 시 모두 동작
}
// .. 이후 동작
예외가 발생하는 곳을 예측하여
try에 작성하고
예외가 발생 시 catch문에서 파악하고
다음과정으로 넘어간다.
즉, 비정상적으로 중단되는걸 막을 수 있다.
throw(던지다)
- 예외 객체를 CATCH로 전달하는 구문
throws
- 해당 메서드에서 발생되는 예외 클래스를 선언( 예외 처리가 아닌 예외 전가)
- THROWS가 선언된 메서드를 사용하는 클래스에서 예외처리 필요(TRY~CATCH)
- 예외가 발생할 수 있는데 그 예외를 처리해야해! (컴파일할떄 미리 예외를 처리해야 해)
⏬ 호출하는 곳에서 예외처리 해라(예외전가)
스택 트레이스?
프로그램 실행 중 예외가 발생했을때
그 예외가 어디서 발생했는지를 추적하는 정보
- 쉽게 말해 프로그램의 호출 스택(Call Stack)을 추적하여 기록
- 예외가 발생하면 현재 실행중인 메서드와 그 전에 호출된 메서들의 목록(스택)이 제공되는데 이것을 스택 트레이스라 함.
- 스택 트레이스는 매우 유용한 디버깅 도구
public class Main {
public static void main(String[] args) {
methodA();
}
public static void methodA() {
methodB();
}
public static void methodB() {
int result = 10 / 0; // 여기서 ArithmeticException 발생
}
}
🔽
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.methodB(Main.java:11)
at Main.methodA(Main.java:7)
at Main.main(Main.java:3)
그렇다면 finally를 사용하는 이유는?
예제1. db연결 후 끊어주기
database.openConnection();//db접속
try{
result = database.searchData("....");
return result;
}catch(Exception e) {
//데이터 검색 오류
}finally {
database.close(); //DB 접속 종료
}
예제2. try안에 return 문이 있어도 finally를 거친다.
- 함수 자체를 종료하는 부분이 try or catch문에 있어도 무조건 finally를 거친다.
public boolean lookForCarKey() {
//이전 내용 생략
deskDrawer.open(); // 책상서랍을 연다
try{
deskDrawer.searchCarKey();
return true; //💥찾았다면 집을 나선다.
}catch(Exception e) {
//아 어디다 뒀지?
}finally{
deskDrawer.close(); //💥try안에 return이 있어도 무조건 해야할 동작, 책상 서랍을 닫는다
}
// ..이 다음 동작 생략
}
Exception만 사용하여 예외처리?
- 구체적인 예외 구분 불가
- 단순희 Exception으로 잡을 시 각각의 예외에 맞는 적절한 대응을 못함
- 입력문제인지, 네트워크 연결이 문제인지..
- 로그로 찍어서 확인하면 안되나?
- Exception만 사용시 코드가 커지거나 여러곳에서 사용 시 일관된 예외처리가 어려워짐.
- 당장 어떤 오류가 발생하는지 알 수 있지만, 예외를 구체적으로 처리하는것에 비해 비효율적
- 장기적인 상황도 고려해야함.
- 유지보수성
- 문제 해결
- 코드의 가독성과 안정성
💥그럼 아무때나 사용해도 될까?
주로 파일 IO나 서드파티 라이브러리 등 내가 컨트롤할 수 없는 상황에서 실패가 날 수 있겠지????
( Third-Party 라이브러리 : 애플리케이션을 개발 시 직접 작성하지 않은 외부에서 제공되는 라이브러리)
1.외부 소스 접근 시
- DB를 읽을 때나
- 파일을 읽을 때나
2. 네트워크 통신 시
- 다른 웹 호출 시
3. 사용자 입력 처리 시 ... 이 부분은 클라이언트 단에서도 같이 해주기~
4. 리소스 해제 시
- 예외가 발생해도 클린업 작업 가능( 리소스 해제 및 정리 : try-catch-finally )
5. 로그를 기록하여 나중에 문제 진단
6. 재시도
ex) 3번 재시도 해보기~
-> 외부 Dependency를 하지 않으면 사실상 예외처리하는 이유 x
-> 직접 제어를 못하는 부분!!
👀try-catch 남용 시 문제가 될까?
1. 가독성 🚨📉 -유지보수 측면에서 좋지 않음
2.성능저하
- 비용이 올라간다 : 스택 트레이스를 생성하고 예외 처리기를 탐색하는 작업은 추가적인 CPU연산을 요구함.
+ 메모리 사용이 증가됨 : 예외객체 생성, 스택 트레이스 수집 과정에서 메모리 사용 증가
- 속도 : 성능에 민감한 코드에서 남발 시 성능에 악영향을 미칠 수 있음.
for (int i = 0; i < 1000; i++) {
try {
int result = Integer.parseInt("not-a-number"); // 예외 발생
} catch (NumberFormatException e) {
//💥예외처리가 날때마다 실행되면 성능저하가 발생할 수 있으므로, 예외 발생 자체를 최소화하는 방식으로 코드 설계하자
System.out.println("숫자가 아님");
}
}
3. 프로그램 로직 오류
- try-catch문을 남용하면 예외 처리에 의존한 로직이 만들어지고,
정상적인 프름을 예외 처리에 맡기는 것과 같은 잘못된 설계.
- 비정상적인 상황을 처리하기 위해서는 정상적인 프로그램 흐름을 제어하는 도구로 사용해서는 안됨.
try {
int[] numbers = {1, 2, 3};
int result = numbers[3]; // 배열 범위 벗어난 접근
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("배열 범위를 벗어남");
}
4. 디버깅 어려움
- 남용하거나 적절하게 사용하지 않으면 문제의 원인을 찾기가 더 어렵다
- 모든 예외를 포괄적으로 잡아 예외 처리시 구체적인 예외를 놓칠 수 있음. + 디버깅에 드는 시간도 늘어남.
try {
// 예외가 발생할 수 있는 코드
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();//일반적인 방법
}
5. 예외 기록 남기지 않기
try{
//예외 발생!
catch(Exception e){
// 추적하지 않음...
}
추가로~!~
nextInt()에서는 어떤 예외가 나올 수 있을까?
+ 키보드로 입력받는 스트림은 'IN 스트림'이라 부른다.
👀 잠깐!!!
💥그렇다면 항상 써야할까??? 그게 좋은 방법일까?
익셉션 핸들링 보다 더 중요한 개념.. 익셉션 세이프 프로그래밍
유영천 개발자님 왈..
서버가 돌다가 Exception이 나면은 고칠 수라도 있지만...
Exception Handling을 하게되면은 어떻게든 돌아가게 되기에... 사용하게 되면은
나중에 한참 지나서 뻗을수도 있다...
한마디로 디버깅 정보가 없어서 더 디버그가 힘들어진다.
Exception의 문제
어떤 Exception이 나올지 혹은 어떻게 처리할지 또는 처리할때 옳바르게 처리하는게 맞는지? 이것또한 찾기가 어려워진다.
비정상적이게 종료되는걸 막는다는게 초점인거다.
차라리 boolean을 통해서 어떤 부분이 false가 나는지 찾는방법도...
코드를 일단 돌게 만들기 위해 try-catch 사용함으로 끝! <-- 이런 행동은 좋지 못하다..
중요한 부부은
Exception이 나도 문제가 없을 수 있는 코드를 만들려고 생각 정도는 해보자.
Exception Safe programming... 다음에 이어서