1. 오류 메시지 출력 방법
e.printStackTrace() 를 이용한 오류 메시지 출력
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
9
java.lang.ArrayIndexOutOfBoundsException: Index 9 out of bounds for length 8
e.getMessage() 를 이용한 오류 메시지 출력
이 방법은 오류 메시지를 String 타입으로 받아오기만 해서 e.printStackTrace처럼 바로 콘솔에 뿌려주지 않는다. 따라서 print를 직접 해줘야한다.
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
9
Index 9 out of bounds for length 8 오류 발생
2. try ~ catch
에러가 발생할만한 곳에 try를 하고 에러를 catch로 잡는다.
모든 에러의 부모는 (Exception e)로 catch할 수 있으며, 각 에러 타입별로 catch하고 싶다면 아래와 같이 각 에러 타입별로 catch할 수 있다.
(ArrayIndexOutOfBoundsException e) :
(InputMismatchException e) :
import java.util.Scanner;
import java.util.InputMismatchException;
public class ExecClass {
// 1. try ~ catch 를 활용한 exception 예외처리. (예외가 발생할만한 곳에 try 처리를 한다.)
public static void main(String[] args) {
ExTest exTest = new ExTest();
try {
exTest.doAction();
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
}
// // 2. throws Exception (예외가 발생 시 호출한 곳으로 가져와 처리를 한다.)
// public static void main(String[] args){ // 처리할 곳이 있다면... throws Exception으로 ExTest의 doAction2에서 받아온 에러를 다시 위로 던질 수도 있다.
// ExTest exTest = new ExTest();
// Scanner scanner = new Scanner(System.in);
// for (int i = 0; i < 99; i++) {
// try {
// exTest.doAction2();
// } catch (ArrayIndexOutOfBoundsException e) { // try에서 발생한 에러가 인덱스를 벗어난 경우를 catch한다. (인덱스 범위가 0~7인데 8이 들어오는 경우)
// System.out.println("인덱스의 범위를 벗어났습니다. 0 ~ 7 사이로 입력해주세요.");
// } catch (InputMismatchException e) { // try에서 발생한 에러가 데이터 타입이 잘못된 경우를 catch한다. (문자에 숫자가 들어오거나, 숫자에 문자가 들어오는 경우)
// scanner.nextLine(); // int에 잘못 들어와 소거되지 못 하고 무한루프를 발생시키는 문자 찌꺼기 소거용.
// System.out.println("문자를 입력했습니다. 숫자를 입력해주세요.");
// } catch (Exception e) { // 모든 Exception의 부모형태다. 항상 마지막에는 Exception e로 끝내준다. 이 경우는 위에서 인덱스 범위 초과, 데이터 입 에러를 모두 잡아서 마지막 Exception e는 타지 않는다.
// // 위에서 모든 에러를 잡았더라도 혹시 모를 에러에 대비하기 위해 마지막에 모든 에러의 부모형인 Exception e로 끝내줘야한다.
// // 오류 출력 방법 1. e.printStackTrace()
// e.printStackTrace(); // 프로그램이 죽지는 않고 에러메세지를 출력해준다.
// // 오류 출력 방법 2. System.out.println(e.getMessage())
// System.out.println(e.getMessage() + " 오류 발생");
// }
// System.out.println("------------------------------------");
// }
// }
}
import java.util.InputMismatchException;
import java.util.Scanner;
public class ExTest {
// 1. try ~ catch 를 활용한 exception 예외처리. (예외가 발생할만한 곳에 try 처리를 한다.)
public void doAction() {
// TODO Auto-generated method stub
int[] arr = {1, 2, 10, 390, 5, 20, 8, 7};
Scanner scanner = new Scanner(System.in);
// 1.1 try ~ catch 사용의 올바른 예
for (int i = 0; i < 99; i++) {
System.out.println("'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.");
try {
int inputNumber = scanner.nextInt();
scanner.nextLine(); // nextInt return 찌꺼기 소거용.
System.out.println("입력된 숫자에 해당되는 값은 " + arr[inputNumber]);
} catch (ArrayIndexOutOfBoundsException e) { // try에서 발생한 에러가 인덱스를 벗어난 경우를 catch한다. (인덱스 범위가 0~7인데 8이 들어오는 경우)
System.out.println("인덱스의 범위를 벗어났습니다. 0 ~ 7 사이로 입력해주세요.");
} catch (InputMismatchException e) { // try에서 발생한 에러가 데이터 타입이 잘못된 경우를 catch한다. (문자에 숫자가 들어오거나, 숫자에 문자가 들어오는 경우)
scanner.nextLine(); // int에 잘못 들어와 소거되지 못 하고 무한루프를 발생시키는 문자 찌꺼기 소거용.
System.out.println("문자를 입력했습니다. 숫자를 입력해주세요.");
} catch (Exception e) { // 모든 Exception의 부모형태다. 항상 마지막에는 Exception e로 끝내준다. 이 경우는 위에서 인덱스 범위 초과, 데이터 입 에러를 모두 잡아서 마지막 Exception e는 타지 않는다.
// 위에서 모든 에러를 잡았더라도 혹시 모를 에러에 대비하기 위해 마지막에 모든 에러의 부모형인 Exception e로 끝내줘야한다.
// 오류 출력 방법 1. e.printStackTrace()
e.printStackTrace(); // 프로그램이 죽지는 않고 에러메세지를 출력해준다.
// 오류 출력 방법 2. System.out.println(e.getMessage())
System.out.println(e.getMessage() + " 오류 발생");
}
System.out.println("------------------------------------");
}
// // 1.2 try ~ catch 사용의 잘못된 예
// try {
// int inputNumber = scanner.nextInt();
// System.out.println("입력된 숫자에 해당되는 값은 " + arr[inputNumber]);
// } catch (Exception e) { // 얘는 위로 올라오면 안 된다. 모든 Exception의 부모이기 때문에 반드시 마지막으로 가야한다.
// System.out.println("오류 발생");
// } catch (ArrayIndexOutOfBoundsException e) {
// System.out.println("인덱스의 범위를 벗어났습니다.");
// }
}
// 2. throws Exception (예외가 발생 시 호출한 곳으로 가져와 처리를 한다.)
public void doAction2() throws Exception { // 에러 발생시 호출한 곳으로 보낼거야.
// TODO Auto-generated method stub
int[] arr = {1, 2, 10, 390, 5, 20, 8, 7};
System.out.println("'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.");
Scanner scanner = new Scanner(System.in);
int inputNumber = scanner.nextInt(); // 여기서는 에러 처리를 하지 않는다. 에러 발생시 호출한 곳으로 에러를 던진다.
scanner.nextLine(); // nextInt return 찌꺼기 소거용.
System.out.println("입력된 숫자에 해당되는 값은 " + arr[inputNumber]);
}
}
결과 :
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
7
입력된 숫자에 해당되는 값은 7
------------------------------------
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
8
인덱스의 범위를 벗어났습니다. 0 ~ 7 사이로 입력해주세요.
------------------------------------
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
a
문자를 입력했습니다. 숫자를 입력해주세요.
------------------------------------
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
3. throws exception
예외가 발생 시 호출한 곳으로 가져와 처리를 한다. (일반적으로 throws보다는 예외 발생 부분에서 surround try ~ catch를 하는게 좋다.)
import java.util.Scanner;
import java.util.InputMismatchException;
public class ExecClass {
// // 1. try ~ catch 를 활용한 exception 예외처리. (예외가 발생할만한 곳에 try 처리를 한다.)
// public static void main(String[] args) {
// ExTest exTest = new ExTest();
// try {
// exTest.doAction();
// } catch (Exception e) {
// // TODO: handle exception
// System.out.println(e.getMessage());
// }
// }
// 2. throws Exception (예외가 발생 시 호출한 곳으로 가져와 처리를 한다.)
public static void main(String[] args){ // 처리할 곳이 있다면... throws Exception으로 ExTest의 doAction2에서 받아온 에러를 다시 위로 던질 수도 있다.
ExTest exTest = new ExTest();
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 99; i++) {
try {
exTest.doAction2();
} catch (ArrayIndexOutOfBoundsException e) { // try에서 발생한 에러가 인덱스를 벗어난 경우를 catch한다. (인덱스 범위가 0~7인데 8이 들어오는 경우)
System.out.println("인덱스의 범위를 벗어났습니다. 0 ~ 7 사이로 입력해주세요.");
} catch (InputMismatchException e) { // try에서 발생한 에러가 데이터 타입이 잘못된 경우를 catch한다. (문자에 숫자가 들어오거나, 숫자에 문자가 들어오는 경우)
scanner.nextLine(); // int에 잘못 들어와 소거되지 못 하고 무한루프를 발생시키는 문자 찌꺼기 소거용.
System.out.println("문자를 입력했습니다. 숫자를 입력해주세요.");
} catch (Exception e) { // 모든 Exception의 부모형태다. 항상 마지막에는 Exception e로 끝내준다. 이 경우는 위에서 인덱스 범위 초과, 데이터 입 에러를 모두 잡아서 마지막 Exception e는 타지 않는다.
// 위에서 모든 에러를 잡았더라도 혹시 모를 에러에 대비하기 위해 마지막에 모든 에러의 부모형인 Exception e로 끝내줘야한다.
// 오류 출력 방법 1. e.printStackTrace()
e.printStackTrace(); // 프로그램이 죽지는 않고 에러메세지를 출력해준다.
// 오류 출력 방법 2. System.out.println(e.getMessage())
System.out.println(e.getMessage() + " 오류 발생");
}
System.out.println("------------------------------------");
}
}
}
import java.util.InputMismatchException;
import java.util.Scanner;
public class ExTest {
// 1. try ~ catch 를 활용한 exception 예외처리. (예외가 발생할만한 곳에 try 처리를 한다.)
public void doAction() {
// TODO Auto-generated method stub
int[] arr = {1, 2, 10, 390, 5, 20, 8, 7};
Scanner scanner = new Scanner(System.in);
// 1.1 try ~ catch 사용의 올바른 예
for (int i = 0; i < 99; i++) {
System.out.println("'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.");
try {
int inputNumber = scanner.nextInt();
scanner.nextLine(); // nextInt return 찌꺼기 소거용.
System.out.println("입력된 숫자에 해당되는 값은 " + arr[inputNumber]);
} catch (ArrayIndexOutOfBoundsException e) { // try에서 발생한 에러가 인덱스를 벗어난 경우를 catch한다. (인덱스 범위가 0~7인데 8이 들어오는 경우)
System.out.println("인덱스의 범위를 벗어났습니다. 0 ~ 7 사이로 입력해주세요.");
} catch (InputMismatchException e) { // try에서 발생한 에러가 데이터 타입이 잘못된 경우를 catch한다. (문자에 숫자가 들어오거나, 숫자에 문자가 들어오는 경우)
scanner.nextLine(); // int에 잘못 들어와 소거되지 못 하고 무한루프를 발생시키는 문자 찌꺼기 소거용.
System.out.println("문자를 입력했습니다. 숫자를 입력해주세요.");
} catch (Exception e) { // 모든 Exception의 부모형태다. 항상 마지막에는 Exception e로 끝내준다. 이 경우는 위에서 인덱스 범위 초과, 데이터 입 에러를 모두 잡아서 마지막 Exception e는 타지 않는다.
// 위에서 모든 에러를 잡았더라도 혹시 모를 에러에 대비하기 위해 마지막에 모든 에러의 부모형인 Exception e로 끝내줘야한다.
// 오류 출력 방법 1. e.printStackTrace()
e.printStackTrace(); // 프로그램이 죽지는 않고 에러메세지를 출력해준다.
// 오류 출력 방법 2. System.out.println(e.getMessage())
System.out.println(e.getMessage() + " 오류 발생");
}
System.out.println("------------------------------------");
}
// // 1.2 try ~ catch 사용의 잘못된 예
// try {
// int inputNumber = scanner.nextInt();
// System.out.println("입력된 숫자에 해당되는 값은 " + arr[inputNumber]);
// } catch (Exception e) { // 얘는 위로 올라오면 안 된다. 모든 Exception의 부모이기 때문에 반드시 마지막으로 가야한다.
// System.out.println("오류 발생");
// } catch (ArrayIndexOutOfBoundsException e) {
// System.out.println("인덱스의 범위를 벗어났습니다.");
// }
}
// 2. throws Exception (예외가 발생 시 호출한 곳으로 가져와 처리를 한다.)
public void doAction2() throws Exception { // 에러 발생시 호출한 곳으로 보낼거야.
// TODO Auto-generated method stub
int[] arr = {1, 2, 10, 390, 5, 20, 8, 7};
System.out.println("'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.");
Scanner scanner = new Scanner(System.in);
int inputNumber = scanner.nextInt(); // 여기서는 에러 처리를 하지 않는다. 에러 발생시 호출한 곳으로 에러를 던진다.
scanner.nextLine(); // nextInt return 찌꺼기 소거용.
System.out.println("입력된 숫자에 해당되는 값은 " + arr[inputNumber]);
}
}
결과 :
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
7
입력된 숫자에 해당되는 값은 7
------------------------------------
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
8
인덱스의 범위를 벗어났습니다. 0 ~ 7 사이로 입력해주세요.
------------------------------------
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
a
문자를 입력했습니다. 숫자를 입력해주세요.
------------------------------------
'{1, 2, 10, 390, 5, 20, 8, 7}' 배열이 있습니다. 인덱스를 선택해 주세요.
3.2 throws execption에 대한 고찰 execption 강제로 발생시켜 위로 던지기
public class ExecClass {
public static void main(String[] args) {
try {
Test1 test1 = new Test1();
test1.doAction();
} catch (Exception e) {
if (e.getMessage().equals("input 1")) {
System.out.println("사용자가 1을 입력했습니다.");
}
}
}
}
import java.util.Scanner;
public class Test1 {
public void doAction() throws Exception {
Scanner s = new Scanner(System.in);
int inputNumber = s.nextInt();
if(inputNumber ==1) {
throw new Exception("input 1");
}
}
}
이 예제를 실행해보면 어떤 것인지 감을 잡을 수 있다.
우선 execption은 에러가 발생시 담아내는 공간이다.
그 중에서도 Execption은 모든 예외의 최상단 부모다. (모든 에러를 다 담을 수 있다.)
// 조건이 참인 경우 실행
if (조건) {
로직
}
// 조건이 에러(execption)인 경우 참이고 그 때 실행
catch (조건) {
로직
}
if ~ else if ~ else 구문은
try ~ catch ~ catch 구문과 크게 다르지 않다.
A클래스가 B 클래스의 메소드를 실행했다. 그런데 B 클래스의 메소드가 에러가 발생할 경우 B가 죽어버린다. 그래서 B는 try ~ catch로 에러가 나도 죽지 않도록 보호를 한다.
하지만 B가 메소드를 throws Execption으로 정의할 경우 B는 에러를 처리하지도 않고, 에러 발생 시 죽는 대신 호출한 쪽에 에러를 담은 execption을 던져준다. 그러면 A가 그 에러를 받게 되는데, 이 때 A가 에러 처리를 하는 로직이 없다면 죽어버린다. 따라서 A가 에러 처리 하는 로직을 넣어주어 보호를 한다.
즉, try ~ catch와 throws Execption의 차이는 에러가 발생 시 프로그램이 죽는 대신 단지 그것을 잡아내 보호하는 로직을 어디에 오려 붙일거냐의 차이다.
위 예제의 경우 B가 Execption에 일부러 값을 넣고 던져 올리니 A는 A가 넣을 값을 가져와 처리하게 되는 것이다. 즉, execption이라는 공간에 값이 있어서 실행한 것이다. 단지 그것 뿐...
'개발자 > Java' 카테고리의 다른 글
Java (자바) ArrayList 정렬하기 (Comparator 이용) (0) | 2020.05.25 |
---|---|
Java (자바) JCF(Java Collection Framework) - List, Set, Map (0) | 2020.05.24 |
Java (자바) 상점 만들기 (0) | 2020.05.24 |
Java (자바) 실습 Spring을 이용해 DB 생성하고 밀어넣고 조회하기 (0) | 2020.05.22 |
Java (자바) Spring, Apache Tomcat (0) | 2020.05.22 |