[자바/Java] 예외처리란?
resilient
·2021. 1. 15. 12:47
github.com/whiteship/live-study/issues/9
목표
자바의 예외 처리에 대해 학습하세요.
학습할 것 (필수)
- 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
- 자바가 제공하는 예외 계층 구조
- Exception과 Error의 차이는?
- RuntimeException과 RE가 아닌 것의 차이는?
- 커스텀한 예외 만드는 방법
마감일시
2021년 1월 16일 토요일 오후 1시까지.
#자바에서 예외 처리 문 -try-catch문
try {
//예외가 발생할 가능성이 있는 문장들을 넣는다.
}catch(Exception1 e1) {
//Exception1이 발생했을 경우 이를 처리하기 위한 문장.
}catch(Exception2 e2) {
//Exception2이 발생했을 경우 이를 처리하기 위한 문장.
}catch(Exception3 e3) {
//Exception3이 발생했을 경우 이를 처리하기 위한 문장.
}
하나의 try블럭 다음에는 여러 종류의 예외를 처리할 수 있도록 하나 이상의 catch 문이 올 수 있고, 발생한 예외의 종류와 일치하는 catch블럭이 없으면 예외는 처리되지 않는다.
public class Main {
public static void main(String[] args) {
int number = 100;
int result = 0;
for(int i =0;i<10;i++) {
try {
result = number / (int)(Math.random()*10);
System.out.println(result);
} catch (ArithmeticException e) {
//ArithmeticException 은 산술연산과정에서 정수가 0으로 나누는 것이 안되기 때문에 발생하는 오류이다.
System.out.println("0");
}
}
}
}
만약에 try 블럭내에서 예외가 발생하지 않으면 catch 블럭을 아예 거치지 않고 try-catch문을 빠져나오고
예외가 발생하면 발생한 예외와 일치하는 catch블럭이 있는지 확인한다. 일치하는 catch 블럭을 찾게 되면 그 블럭내의 문장들을 수행하고 try-catch 문을 빠져나가서 다음 문장들을 계속해서 수행한다.
하지만 catch블럭의 예외와 try블럭내에서 발생한 예외가 다르면 catch블럭은 처리되지 못한다.
#throw 키워드
throw 키워드를 이용해서 개발자가 고의적으로 예외를 만들 수 있다.
1. 먼저 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만들어준다.
Exception e = new Exception("고의로 발생")
2. throw 키워드를 이용해서 예외를 발생시킨다.
throw e;
public class Main {
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("프로그램종료");
}
}
#throws 키워드
try-catch 문을 이용하는 거 외에 예외를 메소드에 선언하는 방법이 있다.
메소드의 선언부에 throws 키워드를 사용해서 메소드 내에서 발생할 수 있는 예외를 적어주면 된다.
예외가 여러개면 , (쉼표)로 구분해준다.
void method() throws Exception1, Exception2, ... ExceptionN{
//메소드 내용
}
public class Main {
public static void main(String[] args) throws Exception {
method1(); // 같은 클래스내 static 멤버 이므로 객체생성 없이 호출가능.
}
static void method1() throws Exception{
method2();
}
static void method2() throws Exception{
throw new Exception();
}
}
throws로 예외를 선언하면 자식 타입의 예외까지도 발생할 수 있다는 점에 조심해야 한다.
오버 라이딩할 때는 단순히 선언된 예외의 개수가 아니라 상속관계까지 고려해줘야 한다.
예를 들어서 IllegalMonitorStateException 은 RuntimeException 클래스의 자식이기 때문에 IllegalMonitorStateException은 예외 처리를 해주지 않아도 된다.
Java API 문서를 보고 메소드의 선언부와 Thorws 부분을 보고 메소드 끼리 연관 지어서 확인해주는 것이 좋다.
#finally 키워드
finally 키워드 블럭은 예외의 발생 여부와 상관없이 실행되어야 하는 코드를 포함시키는 역할을 한다.
try-catch문의 끝에 선택적으로 덧붙여 사용할 수 있으며 try-catch-finally의 순서로 구성된다.
try {
//예외 발생가능성 문장
}catch (Exception1 e1) {
//예외발생시 예외처리 문장
}finally {
//항상 수행되어야 하는 문장
}
#자바가 제공하는 예외 계층 구조
자바에서는 실행 시 발생할 수 있는 오류(Exception 과 Error)를 클래스로 정리하였다.
모든 클래스의 조상은 Object이고 Exception과 Error 클래스 역시 Object클래스의 자식들이다.
#RuntimeException과 RE가 아닌 것의 차이는?
- RE클래스 들은 주로 개발자 실수에 의해서 발생될 수 있는 예외들로 자바의 프로그래밍 요소들과 관계가 있다. 예를 들어 배열의 범위를 벗어나거나, 값이 null인 참조 변수의 멤버를 호출하거나, 클래스 간의 형 변환을 잘못하거나 하는 경우에 발생한다.
- RE가 아닌 예외의 클래스들에서는 외부의 영향으로 발생할 수 있는 것들로서, 프로그램을 사용하는 사용자들의 동작에 의해서 발생하는 경우가 많다. 실수로 클래스의 이름을 잘못 적거나, 입력한 데이터 형식이 잘못되거나 하는 경우에 발생한다.
#에러와 예외 (Error와 Exception의 차이점)
프로그램이 실행 중에 어떤 원인에 의해서 오작동을 하거나 비정상적으로 종료되는 경우가 있는데 이럴 때 원인을 에러, 또는 오류라고 한다.
에러는 발생 시점에 따라 컴파일 에러, 런타임 에러, 논리적 에러로 나눌 수 있다.
컴파일 에러는 컴파일 시에 발생하는 에러, 런타임에러는 실행 시에 발생하는 에러이고, 논리적 에러는 실행은 되는데 의도와 다른 게 동작하는 에러이다.
'에러' 는 일단 발생하면 복구할 수 없는 심각한 오류이고
'예외' 는 발생하더라도 수습될 수 있는 상대적으로 덜 심각하다.
예외처리의 정의는 프로그램 실행 시 발생할 수 있는 예외에 대비한 코드를 작성하는 것이고,
예외처리의 목적은 프로그램의 비정상적인 종료를 막고 정상적인 실행상태를 유지하는 것이다.
#커스텀한 예외 만드는 방법
보통은 Exception 클래스나 RuntimeException클래스로 부터 상속받아 클래스를 만들지만, 커스텀해서 만들 수 있다.
class MyException extends Exception{
MyExcetpion(String msg){//문자열을 매개변수로 받는 생성자
super(msg); //부모인 Exception클래스의 생성자를 호출한다.
}
}
요즘은 예외처리를 선택적으로 할 수 있도록 Exception이 아닌 RE 를 상속받아서 작성하는 쪽으로 바뀌어가고 있다.
public class Main {
public static void main(String[] args) {
try {
startInstall();
copyFiles();
}catch(SpaceException e) {
System.out.println("에러 :"+ e.getMessage());
e.PrintStackTrace();
System.out.println("공간확보후 다시설치");
}
}
}
class SpaceException extends Exception{
SpaceException(String msg){
super(msg);
}
}
'Language > Java & Kotlin' 카테고리의 다른 글
[자바/Java] 애노테이션(annotation)이란? (0) | 2021.02.17 |
---|---|
[자바/Java] 열거형(enum) 이란? (0) | 2021.01.30 |
[자바/Java] 인터페이스(Interface)란? (0) | 2021.01.08 |
[자바/Java] 패키지(package) 란? (0) | 2021.01.05 |
[자바/Java] 데이터 타입, 변수 그리고 배열 (0) | 2020.12.27 |