[Exception-2] try-catch, finally, throw

seratpfk·2022년 8월 4일
0

JAVA

목록 보기
80/96

try-catch

  • 예외를 처리할 때 사용하는 코드
  • 실행할 코드는 try 블록에 두고 예외를 처리할 코드는 catch 블록에 두는 방식
  • try 블록의 코드를 실행하다가 예외가 발생되면 발생된 예외는 자동으로 catch 블록으로 전달됨
  • 모든 예외는 자바 클래스로 만들어져 있음
  • 형식:
    try {
    실행코드
    } catch(예외타입선언 e) {
    예외처리코드
    }

try-catch 예시

	public static void m1() {
		try {
			String[] hobbies = new String[3];
			hobbies[1] = "swimming";
			hobbies[2] = "running";
			for(String hobby : hobbies) {  
				System.out.println(hobby.substring(0, 2));  // null 값 때문에 오류 발생
			}
		} catch(Exception e) {  // RuntimeException, NullPointerException 가능
			System.out.println("NullPointerException 발생");
		}
	}

출력:
NullPointerException 발생

연습문제1

	public static void m2() {
		try {
			String input = "20,21,22,,23,24,25";
			String[] inputs = input.split(",");
			int[] ages = new int[inputs.length];  // 길이가 6인 배열 만들기
			for(int i = 0; i < inputs.length; i++) {
				ages[i] = Integer.parseInt(inputs[i]);
				System.out.println("변환 값 : " + ages[i]);
			}
		} catch(NumberFormatException e) {  // RuntimeException, Exception 가능
			System.out.println("NumberFormatException 발생");
		} catch(Exception e) {
			System.out.println("Exception 발생");
		}
	}
  • Exception은 NumberFormatException을 포함하기 때문에 catch(Exception e)를 먼저 작성하면 오류가 난다.

출력:
변환 값 : 20
변환 값 : 21
변환 값 : 22
NumberFormatException 발생

연습문제2

	public static void m3() {
		try {
			Scanner sc = new Scanner(System.in);
			System.out.println("정수1 >>> ");
			int a = sc.nextInt();
			System.out.println("정수2 >>> ");
			int b = sc.nextInt();
			System.out.println(a + "+" + b + "=" + (a+b));
			System.out.println(a + "-" + b + "=" + (a-b));
			System.out.println(a + "*" + b + "=" + (a*b));
			System.out.println(a + "/" + b + "=" + (a/b));
			System.out.println(a + "%" + b + "=" + (a%b));
			sc.close();
		} catch(ArithmeticException e) {
			System.out.println("ArithmeticException 발생");
		} catch(InputMismatchException e) {
			System.out.println("InputMismatchException 발생");
		}
	}
  • 정수2에 0 입력시 출력:
    ArithmeticException 발생

  • 소수점 입력시 출력:
    InputMismatchException 발생

Checked Exception

	public static void m4() {
		try {
			File file = new File("C:\\sample.txt");
			FileReader fr = new FileReader(file);  // try-catch문이 없으면 실행이 불가능한 Checked Exception
		} catch (Exception e) {
		}
	}

finally 블록

  1. try-catch문 마지막에 추가하는 블록
  2. 언제나 마지막에 실행되는 블록
  3. 생략 가능
    	public static void main(String[] args) {
    			Scanner sc = new Scanner(System.in);
    			try {
    				System.out.println("나이 입력 >>> ");
    				String strAge = sc.nextLine();
    				int age = Integer.parseInt(strAge);
    				System.out.println(age >= 20 ? "성인" : "미성년자");
    			} catch (Exception e) {
    				System.out.println("예외 발생");
    			} finally {
    				sc.close();
               System.out.println("finally 블록 실행");
    			}
    		}
  • 소수점 입력 시 출력:
    예외 발생
    finally 블록 실행

throw

  1. 예외 객체를 만들어서 직접 throw할 수 있다.
  2. 자바는 예외로 인식하지 않지만 실제로는 예외인 경우에 주로 사용된다.
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		try {
			System.out.println("나이 입력 >>> ");
			String strAge = sc.nextLine();
			int age = Integer.parseInt(strAge);
			if(age < 0 || age > 100) {
				throw new RuntimeException("나이는 0 이상 100 이하만 가능합니다.");
			}
			System.out.println(age >= 20 ? "성인" : "미성년자");
		} catch (Exception e) {
			System.out.println("예외 발생");
		} finally {
			sc.close();  // 실제로 finally는 자원을 반납할 때 주로 사용됨
			System.out.println("finally 블록 실행");
		}
	}
  • throw는 예외 발생해도 출력되지 않고, catch문의 e가 받는다.

출력:
나이 입력 >>>
10000000
예외 발생
finally 블록 실행

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		try {
			System.out.println("나이 입력 >>> ");
			String strAge = sc.nextLine();
			int age = Integer.parseInt(strAge);
			if(age < 0 || age > 100) {
				throw new RuntimeException("나이는 0 이상 100 이하만 가능합니다.");
			}
			System.out.println(age >= 20 ? "성인" : "미성년자");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			sc.close();  // 실제로 finally는 자원을 반납할 때 주로 사용됨
			System.out.println("finally 블록 실행");
		}
	}
  • catch 블록의 System.out.println("예외 발생");를
    System.out.println(e.getMessage());로 바꾸면
    throw new RuntimeException("나이는 0 이상 100 이하만 가능합니다.");가 나온다.

출력:
나이 입력 >>>
1000000
나이는 0 이상 100 이하만 가능합니다.
finally 블록 실행

throws

  • 메소드 외부로 예외를 던질 때 throws문을 이용해 던지는 예외를 명시함.
  • 2개 이상의 예외를 명시할 수 있기 때문에 throw가 아닌 throws라고 함.
    public class ParkingLot {
    	private Car[] cars;
    	private int idx;
    	private Scanner sc;
    	public ParkingLot() {
    		cars = new Car[10];
    		sc = new Scanner(System.in);
    	}
    	public void addCar() throws RuntimeException {
    			if(idx == 0) {
    				throw new RuntimeException("FULL");
    			}
    	}
    	public void deleteCar() throws RuntimeException {
    			if(idx == 0) {
    				throw new RuntimeException("EMPTY");
    			}
    	}
    	public void findCar() throws RuntimeException {
    		if(idx == 0) {
    			throw new RuntimeException("EMPTY");
    		}
    	}
    	public void printAllCars() throws RuntimeException {
    		if(idx == 0) {
    			throw new RuntimeException("EMPTY");
    		}
    	}
    	public void manage() {
    		while(true) {
    			try {
    				System.out.print("1. 추가 2. 제거 3. 조회 4. 전체목록 0. 종료 >>> ");
    				int choice = sc.nextInt();
    				switch(choice) {
    				case 1 : addCar(); break;
    				case 2 : deleteCar(); break;
    				case 3 : findCar(); break;
    				case 4 : printAllCars(); break;
    				case 0 : return;
    				default : throw new RuntimeException("Bad Request");
    				}
    			} catch(InputMismatchException e) {
    				sc.next();
    				System.out.println("처리 명령은 정수(1~4,0)입니다.");
    			} catch(RuntimeException e) {
    				System.out.println(e.getMessage());
    			}
    		}
    	}
    	public static void main(String[] args) {
    		new ParkingLot().manage();
    	}
    }

사용자 정의 예외 클래스

  • Exception 클래스를 상속 받는다.
  • Serializable 인터페이스 : 이 인터페이스를 구현하면 직렬화가 가능. serialVersionUID 값을 가져야 함(추천)
  • Throwable 클래스 : serialVersionUID 값이 필요함
  • Exception 클래스 : serialVersionUID 값이 필요함
  • MyException 클래스 : serialVersionUID 값이 필요함

    MyException 클래스

    public class MyException extends Exception {
    	private static final long serialVersionUID = -2605896340659853763L;
    	private int errorCode;
    	public MyException(String message, int errorCode) {
    		super(message);
    		this.errorCode = errorCode;
    	}
    	public int getErrorCode() {
    		return errorCode;
    	}
    	public void setErrorCode(int errorCode) {
    		this.errorCode = errorCode;
    	}
    }
> ## ParkingLot 클래스
 ```java
 public class ParkingLot {
	private Car[] cars;
	private int idx;
	private Scanner sc;
	public ParkingLot() {
		cars = new Car[10];
		sc = new Scanner(System.in);
	}
	public void addCar() throws MyException {
		if(idx == cars.length) {
			throw new MyException("Full", 1000);  // 에러코드 1000
		}
	}
	public void deleteCar() throws MyException {
		if(idx == 0) {
			throw new MyException("EMPTY", 2000);  // 에러코드 2000
		}
	}
	public void manage() {
		while(true) {
			try {
				System.out.println("1.추가 2.삭제 3.종료 >>> ");
				int choice = sc.nextInt();
				switch(choice) {
				case 1: addCar(); break;
				case 2: deleteCar(); break;
				case 0: return;
				default: throw new RuntimeException("Bad Request");
				}
			} catch(MyException e) {
				System.out.println(e.getMessage() + "[" + e.getErrorCode() + "]");
			} catch(InputMismatchException e) {
				sc.next();
				System.out.println("처리 명령은 정수만 가능");
			} catch(RuntimeException e) {
				System.out.println(e.getMessage());
			}
		}
	}
	public static void main(String[] args) {
		new ParkingLot().manage();
	}
}

0개의 댓글