- Error(오류)와 Exception(예외사항)
Error(오류) | 프로그램이 실행될 수 없는 오류 |
프로그램이 실행중에 처리할 수 없음(코드를 고쳐야 실행 가능) | |
ex.오타 | |
Exception(예외사항) | 프로그램 실행 중에 발생하는 오류 |
수습 코드를 통해 실향할 수 있는 오류 |
- 예외처리
수습 코드를 작성하여 사전에 예외로 인한 프로그램의 비정상적 종료를 미연에 방지하는 작업
- 주요 예외 사항
ArithmeticException | 수학적으로 해결할 수 없는 예외 |
NullPointException | 인스턴스가 생성되지 않았다. |
ArrayIndexOutOfBoundsException | 배열 범위 밖 |
ex. 0~9까지인데 10번 사용할 경우 | |
NumberFormatException | 숫자로 변환할 수 없음 |
ex. Scanner 사용해서 다 문자열로 받아서 숫자로 변환할 때 숫자가 아니여서 변환할 수 없을 경우(one, 하나, ... 입력시) | |
IOException | 입출력 예외(파일 입출력 포함) |
SQLException | DB 처리 관련 예외 |
- 예외 사항의 처리
try (시도하다) |
예외 사항이 발생될 수 있는(가정) 코드를 작성하는 부분. |
정상적으로 처리될 수도 있으며, 코드를 작성할 때는 잘 처리될 것으로 생각하며 작성함. | |
catch (예외사항을 잡아서 처리하다) |
try부분에서 예외사항이 발생되면 처리해야할 작업 코드를 작성하는 부분(문제에 대한 출력문 등...) |
catch 부분은 예외사항에 따라 여거개가 존재할 수 있음. | |
finally (반드시 마지막에 실행하다) |
생략할 수 있는 부분. 예외가 없어도, 예외가 있어도 마지막에 실행되야하는 코드를 작성하는 부분. |
마지막에 실행할 작업이 없으면 작성하지 않아도 됨. |
- 처리 순서
1. 메소드 안에서 자체적으로 처리 | try, catch 구문을 사용 |
2. 호출한 메소드에서 처리하도록 예외를 넘김 | 반환형 메소드() throws 예외사항 { ... } |
메소드를 호출한 위치에 try, catch를 사용하여 예외를 처리해야함. |
- Multi-catch
catch부분은 여러개를 작성할 수 있음.
try {
//숫자 입력 처리
//나눗셈 처리
} catch (NumberFormatException ne) { //(1)
... //숫자를 입력해야 합니다.
} catch (ArithmeticException ae) { //(2)
... //0으로 나눌 수 없습니다.
} catch (Exception e) { //(3)
... //그 외의 예외사항 처리
}
작성 순서대로 실행됨.
(1)이 아니면 (2), (2)도 아니면 (3) catch 부분 실행.
마지막에 큰 범위의 예외사항이 와야함.
-호출하는 메소드에게 예외사항 전달
throws Exception 클래스1, Exception 클래스2.., Exception 클래스n
메소드 선언 뒤쪽에 throws 키워드로 사용하여 예외사항 클래스를 입력하면 호출한 메소드에 발생한 예외사항을 넘길 수 있음
다양한 예외사항을 처리해야 할 경우 ','로 구분하여 여러 개의 예외사항 클래스를 입력할 수 있음.
-예외사항 일부러 만들기
예외 사항 인스턴스를 만들어서 보내기.
Exception 클래스로 예외사항 인스턴스를 생성
- 생성 시 메시지로 사용할 문자열 추가
Exception ex = new Exception("메시지");
- throw 키워드를 사용하여 예외 인스턴스 전달
throw ex;
이 때 메소드는 예외를 전달하기 때문에 throws로 예외를 선언해야 함.
public void method() throws Exception { ... }
- 에러 코드와 메시지를 갖는 예외 클래스 만들기(작성 단계)
1. Exception 클래스를 상속하여 새로운 클래스(MyException) 작성 |
2. 작성한 새로운 클래스로 인스턴스 생성 |
3. 생성 시 메시지, 에러코드 등 값 추가 |
4. 새로 만든 예외사항임을 알려야함. throws 뒤에 클래스 이름을 작성. |
5. 메소드를 호출하는 곳에서 새로운 클래스로 catch 처리. catch 부분에서 새로운 클래스의 정보를 출력 및 처리. |
예제)
com.dto.package > Infomation.java
package com.dto;
public class Information {
private String name;
private String info;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
com.package > ExceptionTest.java
package com;
import java.util.Scanner;
import com.dto.Information;
public class ExceptionTest {
static Information info = new Information();
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("이름 : ");
info.setName(scan.nextLine());
System.out.print("정보 : ");
info.setInfo(scan.nextLine());
}
}
static Informationinfo = new Information();에서 =new Information()을 붙이기 전에는 참조변수(선언만 되어있고 아무것도 없는 상태이기 때문에) NullPointerException이 발생한다.
com.package > CalculatorTest.java
1. 덧셈(예외 사항 자체 처리)
package com;
import java.util.Scanner;
public class CalculatorTest {
static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
String menu = "";
while(true) {
System.out.println();
System.out.println("예외처리 계산기");
System.out.println("1. 덧셈");
System.out.println("2. 뺄셈");
System.out.println("3. 나눗셈");
System.out.println("4. 예외 발생");
System.out.println("0. 종료");
System.out.print("선택>> ");
menu = scan.nextLine();
if(menu.equals("0")) {
System.out.println("종료");
break;
}
switch(menu) {
case "1":// 덧셈 처리(예외사항 자체 처리)
add();
break;
private static void add() {
int n1, n2, rs;
String str;
System.out.println("덧셈 연산");//서브 타이틀
try {
System.out.print("첫번째 수 : ");
str = scan.nextLine();
n1 = Integer.parseInt(str);
System.out.print("두번째 수 : ");
str = scan.nextLine();
n2 = Integer.parseInt(str);
rs = n1 + n2;
System.out.println("계산 결과 : " + rs);
} catch(Exception ne) {
System.out.println("숫자를 입력해 주세요.");
} finally {
System.out.println("덧셈 연산이 끝났습니다.");
}
}//add 끝
어떤 예외사항일지 모를 경우에는 가장 높은 Exception으로 모든걸 받아서 사용할 수 있음.
인스턴스로 모든게 처리된다. 즉, 예외 사항도 인스턴스이다.
2. 뺄셈(예외 사항 떠넘기기)
case "2":// 뺄셈 처리(예외사항 떠넘기기)
try {
subManage();
} catch (NumberFormatException e) {
System.out.println("숫자를 입력해 주세요.");} catch (Exception e) {
System.out.println("숫자를 입력해 주세요.");
}
break;
private static void sub() throws NumberFormatException, Exception {
int n1, n2, rs;
String str;
System.out.println("뺄셈 연산");
System.out.print("첫번째 수 : ");
str = scan.nextLine();
n1 = Integer.parseInt(str);
System.out.print("두번째 수 : ");
str = scan.nextLine();
n2 = Integer.parseInt(str);
rs = n1 - n2;
System.out.println("계산 결과 : " + rs);
}
public static void subManage() throws NumberFormatException, Exception{
sub();
}
}
sub에서 전달되는 걸 subManage가 받아서 전달하는 흐름을 만들기 위해 subManage();를 작성해준다.
오류 발생시 가장 가까운 catch문이 받고, 아니면 다른 예외사항으로 다시 던진다.
다른 예외사항 발생할 경우를 대비해서 catch (Exception e)를 만들어준다.
Exception이 더 크기 때문에 나중에 써줘야함(먼저 작은 범위인 NumberFormatException부터 사용한다.)
NumberformatException, Exception에 대한 try, catch는 case문에 적어준다.
메소드 부른 곳에서 처리하기 때문에 메소드 이름 뒤에 throws exception을 작성해준다.
3. 나눗셈(자체처리, 떠넘기기)
case "3":// 나눗셈 처리(자체 처리도 하고 떠넘기기도 하고)
try {
div();
} catch (NumberFormatException e) {
System.out.println("숫자를 입력해주세요.");
}
break;
private static void div() throws NumberFormatException{
int n1, n2, rs;
String str;
System.out.println("나눗셈 연산");//서브 타이틀
System.out.print("첫번째 수 : ");
str = scan.nextLine();
n1 = Integer.parseInt(str);
System.out.print("두번째 수 : ");
str = scan.nextLine();
n2 = Integer.parseInt(str);
try {
rs = n1 / n2;
} catch (ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다.");
rs = 0;
}
System.out.println("계산 결과 : " + rs);
}
Exception으로만 하면 위에서 처리해야할 부분까지 전체 처리해주므로 오류 발생함.
if문 | 사전에 비교(true, false) |
try~catch문 | 무조건 계산을 실행하고 봄, 안되면 예외사항으로 실행 |
if문 대신 try~catch문 사용하는 이유 | if문은 연산이 필요하지만, 예외사항은 연산이 필요없기 때문에 사용한다. |
4. 에외 사항 일부러 발생시켜서 처리하기
case "4":// 예외를 일부러 발생 시켜서 처리해보기.
try {
makeException();
} catch (MyException e) {
System.out.println(e.getMessage());
System.out.println("에러코드 : " + e.getErrCode());
}
break;
default:
break;
}
}
}
private static void makeException() throws MyException{
MyException myexp =
new MyException("페이지를 찾을 수 없습니다.", 404);
throw myexp;
}
'이런 예외사항이 발생할 수도 있다.'라는 가정을 해두는 것이다.
여러 예외를 줄 수 있기 때문에 throws로 사용하며, 특정 문구를 가진 예외 인스턴스 만든다.
Exception myexp = new Exception("일부러 만든 예외사항~");
만든 예외를 던졌을 때 실제로 던져지는 부분은 case "4"의 try~catch문에서 받게된다.
실제로 사용하는 것은 throw myexp;이다. 이 경우 하나만 던지기 대문에 throw로 사용한다.
5. 예외 코드 저장 필드
class MyException extends Exception{
private final int ERR_CODE;
public MyException(String msg, int eCode) {
super(msg);
ERR_CODE = eCode;
}
public int getErrCode() {
return ERR_CODE;
}
}
super(msg)를 사용하기 때문에 부모 클래스의 메시지 출력한다.
return ERR_CODE는 에러코드만 받아서 상수값으로 넘긴다.
-etc
try~catch문 안에 try~catch문을 중첩으로 사용할 수 있음. 하지만 중첩하는 일은 거의 없다.
finally안에 catch 넣어서 사용하는 경우는 종종 있다.
굳이 예외처리 어렵게 (상위로 보내서) 할 필요 없다. method안에서 try~catch 사용해서 예외사항 처리하는게 더 좋음.
'JAVA' 카테고리의 다른 글
0408 JAVA - 문자열의 처리 (0) | 2020.04.08 |
---|---|
0331 JAVA - 객체지향의 특성(추상화) (0) | 2020.03.31 |
0330 JAVA - 객체지향의 특성(다형성) (0) | 2020.03.31 |
0330 JAVA - 객체지향의 특성(상속) (0) | 2020.03.31 |
0327 JAVA - 객체 지향의 특성(상속) (0) | 2020.03.27 |