ch8 예외처리

김민지·2023년 1월 19일
0

자바의정석

목록 보기
7/8

Exception, RuntimeExeption

  • Exception class: 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외-> Checked 예외-> 반드시 예외처리를 해주어야함
  • RuntimeException class: 프로그래머의 실수로 발생하는 예외
    -> unchecked 예외 -> 예외처리를 반드시 해주지 않아도됨

try-catch의 목적

  • 프로그램 실행시 발생할 수 있는 예외가 일어나면 이러한 처리를 통해 프로그램이 비정상적으로 종료되는것을 막기위하여 작성하는 코드

try-catch의 흐름

  • try블럭내에서 예외가 발생한경우 catch문을 찾아서 catch문을 수행하고 try-catch문 이후의 문장을 수행한다
  • 예외가 발생하지 않은경우 catch문은 영원히 수행되지 않는다
   public static void main(String[] args) throws IOException {
        System.out.println("1");
        try{
            System.out.println("2");
            System.out.println(0/0);
            System.out.println("3");
        }catch(ArithmeticException ae){
            System.out.println("4");
        }
        System.out.println("5");
        //1 2 4 5출력, 예외발생이후의 문장은 수행하지 않음
    }
  • 예외가 발생한경우, 예외발생이후의 문장들은 수행하지 않고 바로 catch문으로 이동한다
  • catch문의 예외클래스에 대해 인스턴스가 만들어지고 instanceof연산자로 인스턴스임이 확인이 되면 해당 블록안으로 들어가게된다. 그래서 가장 최상위 예외 클래스인 Exception을 ArithmeticException대신 넣어도 잘 돌아간다

자바는 메서드에 이러한 예외가발생할수있음을 코드로 작성해놔야한다
그래서 프로그래머가 이러한 예외가 발생할 수 있음을 코드만 보고도 짐작할 수 있다

두가지 예외처리 방식

1

public class Main{
    static File createFile(String fileName) throws Exception {
        try{
            if(fileName.isEmpty()) throw new Exception("파일이름이 유효하지 않습니다");
        }catch(Exception e){
            fileName = "제목없음.txt";
        }
        File f = new File(fileName);
        return f;
    }
    public static void main(String[] args) throws Exception {
        System.out.println(createFile(null).getName());

    }
}

2

import java.io.*;
import java.lang.reflect.Array;
import java.nio.Buffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InvalidPropertiesFormatException;
import java.util.Scanner;

public class Main{
    public static File createFile(String str){
        if(str.isEmpty()) new Exception("파일이름이 유효하지 않습니다");
        return new File(str);
    }
    public static void main(String[] args) throws Exception {
        String str = null;
        try{
            File f = createFile(str);
            System.out.println(f.getName() + " 파일이 성공적으로 생성되었습니다");
        }catch(Exception e){
            System.out.println(e.getMessage() + "\n 다시 입력해 주세요");
        }
    }
}

finally는 언제 사용?

  • 예외가 발생하든 안하든 두 경우 모두 이후에 실행되어야하는 코드는 finally에 적어준다

try-catch의 문제

  • 입출력을 한다고 생각해보자. 입출력도중에 예외가 발생할 수 있으므로 try-catch로 감쌀것이다. 그런데 입출력이끝난후에는 꼭 사용한 자원을 반환하기위해 close를 해주어야하는것들이 있다.
    그렇게 되면 try문이 중첩되어 가독성측면에서 좋지 않다.
    그리고 만약 예외가 두군데서 발생하면 앞의 예외가 무시된다는 점에 있다.

try-with-resource

  • try문이 끝나면 자원을 자동으로 반납해준다
  public static void main(String[] args) throws Exception {
        int sum = 0;
        int score =0;
        //try괄호에 객체를 생성한다
        //fis와 dis는 AutoCloseable을 구현한 class여야 try가 끝나고 자동으로 close된다
        try(FileInputStream fis = new FileInputStream("score.txt");
            DataInputStream dis = new DataInputStream(fis)){
             while(true){
                    score = dis.readInt();
                    System.out.println(score);
                    sum += score;
             }
             //try문이 끝나면 위에서 생성한 fis와 dis는 닫히게된다
        }catch(EOFException e){
                System.out.println("점수의 총합: " + sum);
        }catch(IOException e){
                e.printStackTrace();
        }


    }

중간에 예외가 발생해도 둘다 출력해준다

예외되던지기

  • 예를들어 a라는 예외가발생했을때 해당 메서드를 호출한곳, 그리고 해당 메서드 이렇게 두부분에서 에러처리가 필요할땐 다음과같이 해당 메서드에서 에러에 대한 처리를 한 후에 인위적으로 다시 error를 던져준다
public static void func2(){
        try{
            func();//발생한 예외를
        }catch(Exception e){//여기서 받고 아래에서 예외처리2
            System.out.println("예외처리2");
        }
    }
    public static void func() throws Exception {
        try{
            throw new Exception();//예외가 발생했음!
        }catch(Exception e){
            System.out.println("예외처리1");
            throw e;//예외를 다시 던짐
        }
    }

연결된예외

profile
안녕하세요!

0개의 댓글