예외처리
컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용프로그램 실행 오류가 발생하는 것을 자바에서는 에러(error)라고 한다. 에러는 JVM실행에 문제가 생겼다는 것이므로, JVM 위에서 실행되는 프로그램을 아무리 견고하게 만들어도 결국 실행 불능이 된다. 개발자는 이런 에러에 대체할 방법이 전혀 없다. 자바에서는 에러 이외에 예외(Exception)이라고 부르는 오류가 있다. 예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다. 예외가 발생되면 프로그램은 곧바로 종료된다는 점에서는 에러와 동일하다. 그러나 예외는 예외 처리(Exception Handling)를 통해 프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 할 수 있다.
예외에는 두 가지 종류가 있다. 하나는 일반 예외(Exception)이고, 다른 하나는 실행 예외(Runtime Exception)이다. 일반 예외는 컴파일러 체크 예외라고도 하는데, 자바 소스를 컴파일 하는 과정에서 예외 처리 코드가 필요한지 검사하기 때문이다. 만약 예외 처리 코드가 없다면 컴파일 오류가 발생한다. 실행 예외는 컴파일하는 과정에서 예외 처리 코드를 검사하지 않는 예외를 말한다. 컴파일 시 예외 처리를 확인하는 차이일 뿐, 두 가지 예외는 모두 예외 처리가 필요하다. 자바에서는 예외를 클래스로 관리한다. JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성한다. 그리고 나서 예외 처리 코드에서 예외 객체를 이용할 수 있도록 해준다. 모든 예외 클래스들은 java.lang.Exception클래스를 상속받는다.
실행 예외는 자바 컴파일러가 체크를 하지 않기 때문에 오로지 개발자의 경험에 의해서 예외 처리 코드를 삽입해야 한다. 만약 개발자가 실행 예외에 대해 예외 처리 코드를 넣지 않았을 경우, 해당 예외가 발생하면 프로그램은 곧바로 종료된다. 자바 프로그램 개발 경력이 풍부하다면 언제, 어떤 실행 예외가 발생하는지 쉽게 알 수 있지만, 이제 시작하는 개발자라면 자주 실행되는 실행 예외 몇가지를 알아둘 필요가 있다.
1) NullPointerException
이것은 객체 참조가 없는 상태, 즉 null값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생한다. 객체가 없는 상태에서 객체를 사용하려다 보니 예외가 발생하는 것이다.
2) ArrayIndexOutOfBoundsException
배열에서 인덱스 범위를 초과하여 사용한 경우 발생한다. 예를 들어 길이가 3인 int[] arr = new int[3] 배열을 선언했다면, 배열 항목을 지정하기 위해 arr[0] ~ arr[2]를 사용할 수 있다. 하지만 arr[3]을 사용하면 인덱스 범위를 초과했기 때문에 ArrayIndexOutOfBoundException이 발생한다.
3) NuberFormatException
프로그램을 개발하다 보면 문자열로 되어 있는 데이터를 숫자로 변경하는 경우가 자주 발생한다. 문자열을 숫자로 반환하는 방법은 여러 가지가 있지만 가장 많이 사용되는 코드는 다음과 같다.
반환 타입 |
메소드명(매개 변수) |
설명 |
int |
Integer.parseInt(String s) |
주어진 문자열을 정수로 변환해서 리턴 |
double |
Double.parseDouble(String s) |
주어진 문자열을 실수로 변환해서 리턴 |
4) ClassCastException
타입 변환(casting)은 상위 클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에도 발생한다. 이러한 관계가 아니라면 클래스는 다른 클래스로 타입 변환할 수 없다. 억지로 타입 변환을 시도할 경우 ClassCastException이 발생한다.
예외 처리 코드
* try catch finally
Exception 처리 : throws는 사용자한테 이러이러한 Exception이 발생할 수 있다고 알려주는 것, 내가 exception처리안하고 다른곳에서 하도록 넘겨주는 것 그래서 사용자(main)에서 그걸 알고 try catch를 사용해서 쓴다. 따로 exception 을 모아놓는 클래스를 만들어 놓고 catch할 때 모아놓은 클래스의 예외를 불러오는 방법을 많이 쓴다. 그러면 무슨 예외가 발생했는지 사용자에게 알릴 필요 없이 가벼운 예외처리 페이지를 보여주고, 자세한 예외 처리에 관한 정보는 개발자에게 보여주도록 log를 기록하도록 하는 방식을 많이 쓴다.
객체지향은 한 클래스가 모든걸 하면 안된다. 각자 역할을 나눠주는 것이 중요하다.
조상중에 RuntimeException이 없으면 CheckedException 이라고 한다. CheckedException이 발생했을 때 예외처리를 안해주면 comile error가 난다.
무조건 exception 처리를 해줘야한다.(try catch 나 throws를 무조건 해줘야 한다.)
예외는 JVM이 인지한다.JVM이 main메소드에서 한줄 한줄 실행한다. main 메소드에서 throw처리를 해주면 그냥 프로그램이 죽는다. 왜냐면 넘겨주는건데 최종적으로 읽는 애(JVM)가 예외를 넘겨받아서 뭘 못하고 죽는 것이다. 되도록이면 RuntimeException을 쓰는 것이 깔끔.
CheckedException을 쓰면 무조건 예외처리를 써줘야하니깐 귀찮고 지저분하다. 굳이 써야할 경우에만 쓰는게 좋다.
굳이 RuntimeException을 상속받은 클래스를 만드는 이유는 어떤 종류의 예외가 발생했는지 이름을 정해주고 직관적으로 알게하기위함이다.
super는 부모 this는 나
jvm이 예외를 발견했을 때 내부적으로 예외를 발생시킨다. 그거를 try catch로 잡았고, 그 예외를 MyException(ae)로 바꿔서 예외를 발생시킴
Layer?
각각의 코드들이 다양한 예외를 발생시킬 수 있기 때문에 예외들을 모은 공통의 Exception(MyException)을 만들어서 최종적으로 UI에서는 MyException이 발생했다고 처리해주면 된다.
throw MyException으로 사용자 단 까지 예외가 발생했다고 올리기만 하고, 개발자가 볼 log는 따로 기록될 수 있게 처리한다.
콘솔에서 실행하는 프로그램
UI 가 바뀌어도 파일에 명함을
입력받는 로직은 변하지 않는다.
어떤 Exception이 발생하든지 DaoException이 발생하도록
처리할 것이다.
프로그램이 완벽하다는 것을 증명하는 방법은 없다.
가장 멍청한 질문 : 이 프로그램이 완벽합니까?
테스트한 것 까지는 잘 동작한다고 말할 수 있다.
메소드(int i)
화이트박스 테스트(메소드를 잘 안다고 가정)/
블랙박스 테스트 (api를 보고 )
경계값/ 테스트 커버러지?
성수역까지 가는 모든 길을 체크할 수는 없다.
보통 20~30 %만 한다? 일반 회사에서는
메소드를 여러가지 방식으로 실행 시킬 때
main메소드를 많이 만들어서 많이 테스트하면
클래스가 너무 많이 생기기 때문에
JUnit으로 @Test 코드를 작성해서 테스트를 한다.
XXXUI---------->XXXDao------------>파일
- 키보드로 부터 명함정보를 입력 받는다
- 메뉴를 선택
- 결과를 출력 하는 기능
--> 메모리에 자료구조를 가질 수 있다.
--> DaoException을 발생한다.
1. Dao클래스명을 정한다.
-BusinessCardDao
2. Dao가 어떻게 동작할지를 조원들끼리 이야기한다.
3. Dao가 어떤 메소드를 가질지를 정한다.
메소드명, 파라미터, 리턴타입
4. 각자 Dao를 만들고, Test코드를 작성한다.
4번을 하면서 조원끼리 이야기를한다.
무조건 실패하는 테스트코드를 만든다.
->TestDrivenDevelopment
->Test전에 기능 정의를 무조건 해준다.
->사용했을때 오류가 나도록(Assert.assertNotEquals(id, 0);
만든다.
->test도 안하고 그냥 아무생각없이 개발하니깐
->tdd방식으로 (문화) 개발 합시다!
이런식 으로 생긴 문화이다.
페어프로그래밍 ㅋㅋ
'Java' 카테고리의 다른 글
Thread란? (0) | 2019.01.04 |
---|---|
Day 10~11. 친구관리 프로그램 (0) | 2018.12.23 |
IO 패키지 예습 (0) | 2018.12.17 |
Day 9. maven에서 json사용하기 (0) | 2018.12.17 |
어노테이션 (0) | 2018.12.15 |