예외(exception) :
실행 중인 프로그램을 비정상적으로 종료시키지만, 발생할 수 있는 상황을 미리 예측하여 처리할 수 있다,
개발자는 예외 처리를 통해 예외 상황을 처리할 수 있도록 코드의 흐름을 바꿔야 한다.
프로그램이 실행되는 도중 발생하는 예외를 처리하기 위해 try / catch / finally 문을 사용한다.
package 예외처리;
public class finally01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = { 1, 2, 3 };
String s = null;
try {
System.out.println("실행 1");
for (int i = 0; i < arr.length + 1; i++) {
System.out.println(arr[i]);
} // 예외 객체가 던져 졌기떄문에 for 문만 실행 되고
//밑에 있는 3개는 실행 되지 않는다.
System.out.println("실행 2");
s.charAt(0); // 실행 안됌
System.out.println("실행 3");
} catch (NullPointerException e) {
System.out.println(e);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e);
} catch (Exception e) {
System.out.println(e);
} finally {
System.out.println("무조건 실행 되는 fianlly 블록 ");
}
}
}
- try 블록 : 기본적으로 맨 먼저 실행되는 코드로 여기에서 발생한 예외는 catch 블록에서 처리된다.
- catch 블록 : try 블록에서 발생한 예외 코드나 예외 객체를 인수로 전달받아 그 처리를 담당한다.
- finally 블록 : 이 블록은 try 블록에서 예외가 발생하건 안 하건 맨 마지막에 무조건 실행된다.
선택적인 옵션으로 반드시 사용할 필요는 없다.
보통은 사용했었던 자원을 해제할때 사용 되는데, 예를 들면 중단 된 메모리, 데이터베이스 등 자원들을 해제하고 관리하기 위해서 사용 한다. 만약 안하면 시스템이 사용하지도 않는 메모리들을 전부 가지고 만 있어 효율적이지 못하다.
try 안의 코드가 길어지고 다양해지면 별별 예외가 발생 된다. 하지만, catch 블록은 예외객체와 예외처리 될 try 블록 안의 타입이 같아야 실행이 됨으로 catch 구문의 예외객체를 타입별로 다양하게 여러개를 작성해서 미리 대비 하는게 좋다.
catch 에 예외 처리를 최대한 했는데도 catch 문으로 예외 처리를 마지막까지 하지 못한다면, 모든 객체를 업캐스팅하는 클래스인 Exception 을 활용해서 catch(Exception e) 문을 마지막에 넣어주면 모든 예외를 받을 수 있다.
예외 회피하기 (throws 키워드)
메소드 선언부에 throws 키워드를 사용하여 해당 메소드를 사용할 때 발생할 수 있는 예외를 미리 명시할 수도 있다.
이렇게 하면 해당 메소드를 사용할 때 발생할 수 있는 예외를 사용자가 충분히 인지할 수 있으며, 그에 대한 처리까지도 강제할 수 있다. 더욱 안정성 있는 프로그램을 손쉽게 작성할 수 있도록 도와준다는 장점이 있다 .
package 예외처리;
import java.io.IOException;
class Test {
public void f1() throws IOException { // IOException 예외처리를미루겟다.
// 어디로? 이 메서드를 호출하는 쪽이 나타날때까지
int ch = System.in.read();
}
}
public class throws01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test t = new Test(); // 테스트의 객체 생성
try {
t.f1(); // 호출할때 까지 미뤘으니까 이제 예외처리 해주라고 빨간 줄이 뜬다.
// 마우스 올려서 try - catch 눌러서 해주면 되고
// 만약에 또 throws 누르면 그냥 예외처리 안하겠다는 뜻이 되버림.
// 왜? 여기는 메인 클래스라서 끝장을 봐야함
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
예외 발생시키기 (throw 키워드)
throw 키워드를 사용하여 강제로 예외를 발생시킬 수 있다.
사용자 정의 예외 클래스 ( Exception 클래스를 상속)
Exception 클래스를 상속받아 자신만의 새로운 예외 클래스를 정의하여 사용할 수 있다.
사용자 정의 예외 클래스에는 생성자뿐만 아니라 필드 및 메소드도 원하는 만큼 추가할 수 있다.
밑의 예제는 사용자 정의 예외 클래스와 예외를 발생 시키고 미루는 걸 구현 한 예제
package 예외처리;
//사용자 정의 예외 클래스는 최상위 클래스 Exception을 상속 받아 정의한다.
class MyException extends Exception {
public MyException() {
}
// 생성자의 파라미터로 받은 문자열 상위 클래스를 생성자에 전달해주면 예외 메세지로 사용 된다.
public MyException(String s) {
super(s);
}
}
class Test2 {
private int[] datas;
private int cnt;
public Test2() {
datas = new int[3];
}
public void add(int x) throws MyException { // 예외 처리를 미루고
if (cnt == datas.length) { // cnt 가 다 찼으면 배열이 다 찬거니까 /
throw new MyException("배열이 가득 참");
// 예외객체 생성시 생성자에 파라미터로 문자열을 넣어주면 그게 예외 메세지로 사용 됨
// 이제서야 예외를 던져 줘 throw. 그리고 객체 생성 new Exception();
// 이 메서드를 부르는 쪽에서 예외 처리를 하겠다.
}
datas[cnt++] = x; // 그렇지 않으면 cnt 하나 증가 시키겠다~
}
public void printArr() { //배열 프린트 메서드
for (int i = 0; i < cnt; i++) {
System.out.println(datas[i]);
}
}
}
public class throw01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test2 t2 = new Test2();
for (int i = 0; i < 4; i++) {
try {
t2.add(i); // 1 : 여기를 작성 해보면 빨간 줄이 뜨는데 왜?
// 위에서 보다싶이 방이 3갠데 4개 돌리기도 했고 가득찬 배열의 예외객체를 미뤘기에
// 이제 미뤄놓은 예외를 처리 해주면 된다.
} catch (MyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
t2.printArr();
}
}
'JAVA' 카테고리의 다른 글
[JAVA] lang package - object (0) | 2023.03.04 |
---|---|
[JAVA] lang package (0) | 2023.03.04 |
[JAVA] 인터페이스 활용 (0) | 2023.03.04 |
[JAVA] 인터페이스 (0) | 2023.03.04 |
[JAVA] 추상 클래스 (0) | 2023.03.04 |