📖 예외처리 예제 (1)
package day15;
public class Except02 {
public static void main(String[] args) {
//java.lang.ArrayIndexOutOfBoundsException
//System.out.println(args[0]);
/*
args = new String[3];
args[0] = "hello";
*/
try {
System.out.println(args[0]); // 이 코드의 오류가 발생하면
}catch(Exception e) { // 발생한 오류를 e 객체 넣음
System.out.println("인수를 입력하고 실행하세요"); // 예외처리 코드가 실행
System.out.println(e); // 출력해보면 어떤 오류가 발생했는지 뜸
}
System.out.println("---------------");
int number = 100;
int result = 0;
for(int i =0; i< 10; i++) {
//java.lang.ArithmeticException
try {
result = number / (int)(Math.random() * 10);
System.out.println(result);
}catch(ArithmeticException e) {
System.out.println("0으로 나누기 발생");
} // catch
} // for
}
}
🖥️ console 출력 화면
🔈 예외가 발생하여 catch에 작성한 코드가 실행되었다.
두번째 코드에서는 for문 안에 try-catch를 넣어 오류가 나면 예외처리코드가 실행되고 조건식만큼 실행되고 끝났다.
📖 예외처리 예제 (2)
지정하고 싶은 오류가 있다면 써주기, 하지만 이 오류 외에는 예외처리가 안됨
package day15;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Except03 {
public static void main(String[] args) {
// 3개의 정수를 입력받아 합을 구하는 프로그램
Scanner sc = new Scanner(System.in);
System.out.println("정수 3개를 입력하세요");
int sum = 0; // 총합계
int num = 0; // 입력받을 변수
for(int i = 0; i < 3; i++) {
System.out.println(i + " >>");
//java.util.InputMismatchException
try {
num = sc.nextInt(); // int형만 받아야하는데 문자열이 들어올 경우 오류!
}catch(InputMismatchException e) { // 요 오류가 났을시 예외처리 코드 실행
System.out.println("정수가 아닙니다. 다시 입력하세요");
sc.nextLine(); // 버퍼 비우기 (토큰 방식으로 입력받아서)
i--; // 같은 회차의 for문 반복시키기 위해 i 먼저 1감소
continue; // 다음 반복으로 넘어가라 sum+=num 안하고 건너뛰기
}
sum += num;
} // for문
System.out.println("합은: " + sum);
sc.close();
}
}
🖥️ console 출력 화면
🔈 노란색 네모친 부분에서 사용자가 문자열로 잘못입력하여 예외 처리 코드가 실행 되었다. 다시 두번째 수가 입력할 수 있도록 됨
📖 예외처리 예제 (3)
package day15;
public class Except04 {
public static void main(String[] args) {
String [] strNumber = {"23", "25", "213.32","05"};
int i = 0;
try {
for(; i<strNumber.length; i++) {
int j = Integer.parseInt(strNumber[i]);
System.out.println("정수로 변환된 값 : " + j);
}
}catch(NumberFormatException e) { // 숫자로 변형이 안되는 값 오류 났을때 예외처리
System.out.println(strNumber[i] + "는 정수로 변환할수 없습니다.");
}
}
}
🖥️ console 출력 화면
🔈 중간에 오류가 나도 전체 배열의 값이 for문으로 돌아가게 하려면 for문 상단부를 try 위로 올리면 됨
📖 예외처리 예제 (4) - finally
finally는 예외와 상관없이 무조건 실행되는 블럭이다.
package day15;
public class Except05 {
public static void main(String[] args) {
System.out.println(1);
try {
System.out.println(2);
System.out.println(0/0); // ArithmeticException 예외, 0으로 나눌 수 없기 때문에 나타나는 오류
System.out.println(3);
}catch(Exception e) {
System.out.println(4);
}finally {
System.out.println(5);
}
System.out.println(6);
}
}
🖥️ console 출력 화면
🔈 중간에 error가 나서 아래의 3은 출력이 되지 않고 예외처리코드4 - finally블럭에 있는 코드 5가 출력되었다.
System.out.println(0/0);을 주석처리하고 실행하게 되면 1>2>3>5>6 출력된다.
예외와 상관없이 무조건 실행해야할 코드가 없다면 finally는 생략 가능하다.
📖 예외처리 예제 (5) - 강제로 예외 발생 시키기(throws 키워드)
package day15;
public class Except06 {
public static void main(String[] args) {
try {
throw new RuntimeException();
}catch(Exception e) {
System.out.println("예외 발생");
System.out.println(e);
}
System.out.println("-------------");
try {
System.out.println("hello");
throw new Exception("고의로 예외 발생");
//System.out.println("test");
}catch(Exception e) {
System.out.println("에러메서지: " + e.getMessage());
e.printStackTrace(); // 예외 발생시 뜨는 메세지 다시 출력
}
}
}
🖥️ console 출력 화면
🔈 문법적인 오류는 아니여도 논리적인 오류가 있을때 강제로 예외를 발생시킬 수 있다.
📖 예외처리 예제 (6) - 맨 처음 부모클래스인 Exception의 위치
package day15;
public class Except07 {
public static void main(String[] args) {
try {
System.out.println("try 구문");
//throw new Exception("hello"); // 먼저 오면 아래 코드가 당연히 실행되지 않으니
throw new RuntimeException(); // 이클립스가 오류라고 잡아줌
}catch(NullPointerException e) {
System.out.println("null");
}catch(Exception e) { // 제일 부모 이기 때문에 다들 여기로 옴 예외처리 발생시, 맨마지막에 와야함
System.out.println("모든 예외");
}//catch(RuntimeException e) {
//System.out.println("Runtime");
}
}
🖥️ console 출력 화면
🔈 자바의 모든 예외는 Exception의 자식클래스이므로 Exception은 모든 예외를 처리할 수 있다.
catch절에서 Excepion은 모든 예외를 처리할수는 있으나 자식예외보다 먼저 위치할 수는 없다.
📖 예외처리 예제 (7) - 집적처리, throws로 떠넘기기
package day15;
public class Except08 {
// 직접 예외처리 방법
static void add() {
try {
Exception e = new Exception();
throw e;
}catch(Exception e) {
e.printStackTrace();
}
}
// 예외처리 떠넘기는 방법
// 메소드 안에서 예외가 발생하면 메소드 호출한 쪽으로 예외처리 미루기
// 여기서 해결하지 않고 부르는 사람이 해결하렴~^^
static void add() throws Exception {
Exception e = new Exception(); // 나올 수 있는 에러들 같이 작성 가능
throw e;
}
public static void main(String[] args) {
try {
add(); // 불러서 실행하는 곳에서 직접 예외처리
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("프로그램 종료");
}
}
🖥️ console 출력 화면
🔈 예외처리 두가지 방식이 있다.
예외가 발생할 수 있는 코드를 직접 예외처리하거나
직접 처리하지 않고 trows로 호출하는곳에서 처리할 수 있도록 떠넘기기
📖 예외처리 예제 (7) - 호출을 N번에 걸쳐서 했을때의 throw로 떠넘기는 경우
package day15;
public class Except09 {
public static void main(String[] args) {
try {
method1(); // 여기서 처리(3) // 호출순서(1)
}catch(Exception e) {
System.out.println("처리");
e.printStackTrace();
}
}
static void method1() throws Exception { // 부른쪽으로 계속해서 떠넘기기(2)
method2(); // 호출순서(2)
}
static void method2() throws Exception { // 부른쪽으로 계속해서 떠넘기기(1)
throw new Exception(); //호출순서(3)
}
}
🖥️ console 출력 화면
🔈 이때 method1()에서 처리할수도 있지만 method1() 안에서 처리하지 않고 넘겼기에 그 다음번째인 호출한곳에서 처리하게 되었다.
📖 예외처리 예제 (8) - 직접예외처리 후 떠넘기는 경우
package day15;
public class Except10 {
public static void main(String[] args) { // 메인도 토스 시킬 수 있음
try {
method1();
}catch(Exception e) {
System.out.println("main에서 예외 처리");
}
}
static void method1() throws Exception {
try { // 직접 예외 처리
throw new Exception();
}catch(Exception e) {
System.out.println("method1 에서 예외 처리함");
throw e; // catch안에 또 발생되면 토스
}
}
}
🖥️ console 출력 화면
🔈 method1()에서 직접 예외 처리를 했는데 catch 블럭안에서 예외가 강제로 발생하여 이건 토스 시켜서 호출한쪽에서 처리하다.
📘 사용자 정의 예외 클래스 만들기
package day15;
class SpaceException extends Exception{ // Exception 클래스를 상속받고 있음 API에 만들어져 있는 클래스
SpaceException(String msg){ // msg를 매개변수를 받아 수퍼클래스 초기값으로 줌
super(msg);
}
}
class MemoryException extends Exception{
MemoryException(String msg){
super(msg);
}
}
public class Except11 {
public static void main(String[] args) {
try {
startInstall(); // 설치할때 공간이 있는지 먼저 확인
copyFiles();
}catch(SpaceException e) { // 호출한곳에서 예외처리 진행
System.out.println("에러 메세지: " + e.getMessage());
e.printStackTrace();
System.out.println("저장 공간을 확보한 후 다시 설치하시기 바랍니다");
}catch(MemoryException e) {
System.out.println("에러 메세지: " + e.getMessage());
e.printStackTrace();
System.out.println("메모리 부족, 다른 프로그램 종료하시고 시도해주세요");
}finally {
deleteTempFiles(); // 복사해 놓은 파일 삭제
}
}
static void startInstall() throws SpaceException, MemoryException {
if(!enoughSpace()) { // t > f / f > t 값을 반전시켜줌 // ture로 오면 false가 되어 아래 코드가 실행되지 않음
throw new SpaceException("설치 공간이 부족합니다."); // 강제로 예외 만들고, 예외처리 미룸, 부르는곳에서 처리해야함
}
if(!enoughSpace()) {
throw new MemoryException("메모리가 부족합니다.");
}
}
static boolean enoughSpace() {
return true; // true면 공간충분
}
static boolean enoughMemory() {
return false; // true면 메모리 충분
}
static void copyFiles() {}
static void deleteTempFiles() {System.out.println("임시파일 삭제");}
}
🖥️ console 출력 화면
🔈 printStackTrace() 에러가 발생했을때 뜨는 내용을 똑같이 보여준다.
설치공간은 ture로 공간이 충분하여 메세지가 전달되지 않았고, 메모리는 false로 부족하여 MemoryException 메소드로 문자열이 넘어갔다. 거기에서는 Exception을 상속받고 있으며, 메세지를 초기값으로 던져주어 저장됨.
하여 MemoryException 오류가 발생했을시 저장되어 있던 메세지와 에러가 발생했을때 뜨는 메세지가 뜨며(메소드 호출하여 실행됨) finally 블럭은 꼭 실행되기에 마지막으로 출력이 되어있다.
와아아아아 너무 헷갈리고 어렵당당
'basic > java 실습' 카테고리의 다른 글
day 16 예제 - String 클래스, StringBuffer 클래스, Wrapper 클래스 (0) | 2021.05.17 |
---|---|
day 12 연습문제(3) - class(지금까지 배운 것 전부 활용)(난이도상) (0) | 2021.05.14 |
day 15 예제 및 문제 - 싱글톤Singleton, 내부클래스 inner class (0) | 2021.05.12 |
day 14 예제 및 문제- 추상클래스, 인터페이스, 상속 (0) | 2021.05.11 |
day 13 예제 및 문제- 상속과 생성자, 메소드 오버라이딩 (0) | 2021.05.10 |