Be ready to study forever - 개발자 꿈나무
[JAVA문법] 예외처리 본문
예외처리
1. 프로그램 오류
- - 컴파일 에러 – 컴파일 시에 발생 (주로 문법적 오류)
- - 런타임 에러 – 실행 시에 발생하는 에러
- - 논리적 에러 – 실행에는 문제가 없지만 의도와는 다르게 동작하는 에러
Java에서는 실행 시(Runtime)에 발생하는 오류를 ‘에러(error)’ 와 ‘예외(exception)’ 로 정의한다. 에러는 치명적인 오류라서 프로그램 종료를 막을 방법이 없지만 예외는 프로그래머에 의해서 예외처리를 하면 프로그램 종료를 막을 수 있다.
2. 예외 클래스 계층구조
Throwable 클래스를 상속받은 Error클래스와 Exception클래스. 그리고 Exception 클래스는 다시 RuntimeException과 IOEexption에 의해 상속 되어 진다.
- - RuntimeException들을 주로 프로그래머에의해 발생한다(Nullpoint Exception등등)
- - 그 이외에 Exception들은 사용자에 의해 일어나는 경우가 많다
3 예외처리 하기 try -catch 문
아래의 경우처럼 try - catch문으로 작성하여 예외를 핸들링한다. try구문에 여러 개의 catch문 작성이 가능하며 try에서 exception이 발생했을경우 catch에서 하나씩 instanceof검사를 하여 true가 나오는 catch문이 실행된다. 다만, Exception클래스는 모든 exception클래스의 조상이므로 어떤 종류의 예외가 발생하더라도 캐치하여 처리가 된다.
public class example {
try{
//예외 발생 가능성이 있는우 try로 감싼다.
}catch(Exception1 e){
//exception1이 발생했을경우, 이를 핸들링할 문장을 적는다.
}catch(Exception2 e){
//exception2이 발생했을경우, 이를 핸들링할 문장을 적는다.
}catch(Exception3 e){
//exception3이 발생했을경우, 이를 핸들링할 문장을 적는다.
}
}
4. try - catch문의 흐름
- try문 내에서 예외가 발생한 경우
1. 발생한 예외는 일치하는 catch구문이 있는지 확인한다.
2. 일치하는 catch블록이 있다면 그 catch블록만 수행하고 try - catch구문을 빠져나온다. (즉, try부분은 시행되지 않고 일치하는 catch부분만 실행 그리고 빠져나와 계속 프로그램 구동) 만약에, 맞는 catch블록이 없다면 예외처리는 되지 않고 프로그램이 종료된다.
- try문 내에서 예외가 발생하지 않은 경우
1. try문만 실행되고 catch부분은 실행되지 않는다.
5. printStackTrace()와 getMessage()
예외가 발생했을 때 생성되는 인스턴스에 예외정보가 담겨있다. 이를 printStackTrace()나 getMessage()로 확인이 가능하다
- l printStackTrace() – 예외 발생 당시의 호출스택(Call Stack)에 있었던 메서드 정보와 예외 메시지를 출력한다
- l getMessage() – 발생한 예외클래스의 인스턴스에 저장된 메시지를 출력한다.
class ExceptionEx8 {
public static void main(String args[]) {
System.out.println(1);
System.out.println(2);
try {
System.out.println(3);
System.out.println(0/0); // 예외발생!!!
System.out.println(4); // 실행되지 않는다.
} catch (ArithmeticException ae) {
ae.printStackTrace();
System.out.println("예외메시지 : " + ae.getMessage());
} // try-catch의 끝
System.out.println(6);
} // main메서드의 끝
}
6. 예외 발생시키기
1. 먼저 연산자를 new를 이용해 발생시키려는 예외 클라스의 객체를 만든다음
Exception e = new Exception(“Error Message”);
2. throw 키워드를 용해서 예외를 발생시킨다
throw e;
예외 생성 예제
class ExceptionEx9 {
public static void main(String args[]) {
try {
Exception e = new Exception("고의로 발생시켰음.");
throw e; // 예외를 발생시킴
// throw new Exception("고의로 발생시켰음.");
} catch (Exception e) {
System.out.println("에러 메시지 : " + e.getMessage());
e.printStackTrace();
}
System.out.println("프로그램이 정상 종료되었음.");
}
}
7. 메서드에 예외 선언하기
메서드에서 예외를 선언하려면 메서드 선언부에 throws 키워드를 사용해서 발생할 수 있는 예외를 적어 주기만 하면 된다. 예외가 여러 개일 경우 쉼표(,)로 구분한다. 만일 Exception클래스를 선언하면 그 메서드는 모든 종류의 예외가 발생할 가능성이 있다는 것이다.
public void method1() throws Exception1, Exception2, Exception3 {
//메서드 내용
}
public void method2() throws Exception{
//메서드 내용
}
메서드에서 throws로 선언된 예외는 메서드를 호출하는 곳에서 예외처리(try-catch문) or 또다른 throws로 넘기기 등으로 강제하기 때문에 보다 견고한 프로그램을 짤 수 있도록 한다.
8. finally블럭
finally블록은 예외여부와 상관없이 반드시 실행되어지는 코드 블록이다. try-catch문에 마지막에 선언할 수 있으며 예외발생의 경우try – catch – finally로 예외발생이 없는 경우 try-finally순서로 실행되어진다.
class ExceptionEx17 {
public static void main(String[] args)
{
try {
method1();
} catch (Exception e) {
System.out.println("main메서드에서 예외가 처리되었습니다.");
}
} // main메서드의 끝
static void method1() throws Exception {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("method1메서드에서 예외가 처리되었습니다.");
throw e; // 다시 예외를 발생시킨다.
}
} // method1메서드의 끝
}
9.자동 자원 반환 – try-with-resource
try-with-resource문은 주로 I/O입출력관 관련된 클래스를 사용할 때 유용하다. 입출력 클래스 중에는 close()를 해서 메모리 반환을 해야 하는 경우가 종종 있는데 예외처리와 관계없이 close()로 메모리는 반환해야 하기 때문에 try-catch문에서 이를 수행하다 보면 finally 블록에서 close()를 처리한다. 하지만, 이러한 과정이 복잡함으로 자동으로 메모리에서 해제해주는 try-with-resource를 사용 하는 것이 편리하다.
try(FileInputStream fis = new FileInputStream("score.dat");
DataInputStream ids = new DataInputStream(fis)) {
while(true){
score = dis.readInt();
System.out.println(score);
sum += score;
}
}catch(EOFException e){
System.out.println("점수의 총합은" + sum + "입니다.");
}catch(IOException ie){
ie.printStackTrace();
}
10,사용자정의 예외 만들기
가능하면 기존의 예외를 사용하는 것이 좋지만 필요에 따라 사용자 정의 예외도 만들 수 있다. 보통은 Exception클래스나 RuntimeException클래스를 상속받아 사용자 정의 클래스를 만들지만 때에 따라서는 알맞은 클래스를 사용할 수 있다. Exception클래스를 상속받게 되면 checked예외로 반드시 try-catch로 예외처리를 해야만 컴파일 할 수 있다. 반면에 RuntimeExcception클래스를 상속받게 되면 try-catch문으로 예외처리 하지 않아도 컴파일이 가능하다. 따라서, 추세는 RuntimeException을 상속받아 사용자 정의 예외를 만드는 경우가 많다.
- l Exception = try-catch로 처리해주지 않으면 컴파일시 에러발생
- l RuntimeException = try-catch로 처리해 주지 않아도 컴파일은 가능하지만 런타임시 에러가 발생 할 수도 있음
class MyException extends RuntimeException {
private final int ERR_CODE; //상수의 경우 대문자가 관례, 생성자를 통해 초기화된다.
public MyExcpetion(String msg, int errCode){ //생성자
super(msg);
ERR_CODE = errCode;
}
public MyException(String msg){ //생성자
this(msg,100); //ERR_CODE를 100으로 지정해서 초기화
}
public getErrCode(){ //getMessage()와 같이 사용될 메서드
return ERR_CODE; //에러코드를 get하는 메서드
}
}
'Programming > JAVA' 카테고리의 다른 글
[JAVA 문법]Collection Framework - Lists (0) | 2020.07.28 |
---|---|
[JAVA 문법] java.lang패키지 - Math클래스, Wrapper클래스 (0) | 2020.07.25 |
[JAVA 문법] java.lang패키지 - StringBuffer클래스 와 StringBuilder클래스 (0) | 2020.07.25 |
[JAVA 문법] java.lang패키지 - String 클래스 (0) | 2020.07.25 |
[JAVA 문법] java.lang패키지 - Object클래스 (0) | 2020.07.25 |