h-i-s-t-o-r-y

[Java] 예외 처리 (Exception Handling) 본문

Java

[Java] 예외 처리 (Exception Handling)

H' 2021. 7. 17. 23:55

> 에러 (Error == 오류) 란 ?

프로그램 실행중에 어떤 원인에 의해 오작동하거나 비정상적으로 종료시키는 원인

 

> 에러(문제발생) 종류 (발생시점을 기준으로)

ㄱ. 컴파일 에러

ㄴ. 실행(런타임) 에러

    자바에서는..

 

    1) Error - 메모리부족. 스택오버플로우와 같이 복구할 수 없는 심각한 오류

                컴퓨터 하드웨어적인 오작동 -> 오류

 

    2) 예외(Exception) - 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류

                            개발자의 의해서 미리 수습될 수 있는 오류

                            개발자가 발생할 수 있는 예외를 처리...

 

ㄷ. 논리적 에러 - 컴파일X실행X 결과물이 잘못


package days20;

public class Ex01 {

	public static void main(String[] args) {
		
		//컴파일 에러 실행안됨
		//Syntax error, insert ";" to complete
		//int x = 10
		
		//실행하면 에러
		//java.lang.ArrayIndexOutOfBoundsException
		//int [] m = new int[3];
		//m[100] = 100;
		
		//논리적 에러
		//컴파일,실행 되는데 결과물이 잘못됨
		//int m = Integer.MAX_VALUE;
		//long l = m + 100;
		//System.out.println(l);	//-2147483549
		
		//수습될 수 있는 예외
		int x = 10;
		int y = 0;
		//java.lang.ArithmeticException: / by zero
		if (y==0) {	//에러를 막는 작업(예외처리는 아님)
			System.out.println("0으로 나눌 수 없습니다.");
			return;
		}
		double d = x/y;
		// ~~~~~~~~~~Exception 발생
		System.out.println(d);

	}

}
package days20;

import java.util.InputMismatchException;
import java.util.Scanner;

public class Ex02 {

	public static void main(String[] args) {
		// 예외 처리 ...
		/* p.416
		 * Exception in thread "main" java.lang.ArithmeticException: / by zero
			at days20.Ex01.main(Ex01.java:49)
		 * 예외 메시지를 출력하면서 프로그램을 비정상적으로 종료하는 이유는?
		 * 코딩한 것에 예외가 발생했는데 예외처리를 하지 않으면
		 * JVM의 "예외처리기"가 예외발생 객체를 생성해서 메시지 출력하는 역할
		 */
		
		int x = 100;
		int y;
		Scanner scanner = new Scanner(System.in);
		
		do {
			System.out.print("> y 입력 ? ");
			try {
				y = scanner.nextInt();
				break;
			} catch (InputMismatchException e) {
				System.out.println("숫자만 입력하세요.");
				scanner.nextLine();	//System.in.skip(System.in.available());
			}
		} while (true);
		
		// java.util.InputMismatchException
		// 이 예외가 발생했을 때는 다시 입력받도록 예외 처리 ..
		
		
		
		
		/*
		if (y==0) {
			System.out.println("0으로 나눌 수 없습니다.");
			return;
		}
		*/
		
		//try~catch 구문 : 예외처리 방법1
		try {
			// 예외가 발생할 수도 있을거같은 코딩
			double result = x/y;
			//에러 -> ArithmeticException객체생성 -> 아래코드 수행하지 않고 catch로 넘겨짐
			System.out.println(result);
		} catch (Exception e) {
			// Exception e = ArithmeticException 객체 (*다형성*)
			System.out.println(e.toString());	//java.lang.ArithmeticException: / by zero
			e.printStackTrace();	//java.lang.ArithmeticException: / by zero
									//
									//			at days20.Ex02.main(Ex02.java:31)
			//	ㄴ 이거 두개 자주 써요
			System.out.println(e.getMessage());	//	/ by zero
		}
		
//		double result = x/y;
//		System.out.println(result);	//예외처리기가 메시지 출력하며 종료
		

	}//main

}//class

> try~catch 문의 흐름

package days20;

public class Ex04 {

	public static void main(String[] args) {
		// p.420 try~catch 문에서의 흐름
		System.out.println("1");
		try {
			//예외 발생하지 않으면 catch문 안걸림
			System.out.println("2");
			
			//예외 강제로 발생
			int y=10/0;
			//3번 코딩 안해요 catch블럭으로 넘어감
			System.out.println("3");
			
					//자식먼저
		} catch (ArithmeticException e) {
			//여기 catch에 걸리면 다음 catch문은 패스
			System.out.println("7");
		} catch (Exception e) {
			//catch 넘겨졌다고 프로그램 종료하지 않고 5,6으로 넘어감
			System.out.println("4");
		} finally {
			//예외 발생하든 발생하지 않든 처리되는 구문
			//꼭 있어야 되는 코드는 아님
			//DB file close
			System.out.println("finally 구문..");
		}
		
		System.out.println("5");
		System.out.println("6");

	}

}
package days20;

import java.util.InputMismatchException;
import java.util.Scanner;

public class Ex05 {

	public static void main(String[] args) {
		// p.423 멀티 catch 블럭
		// JDK 1.7부터	|기호 (or연산자)
		Scanner scanner = new Scanner(System.in);
		int x = 10;
		int y;
		try {
			System.out.print("> y ? ");
			y = scanner.nextInt();
			double result = x/y;
			System.out.println(result);
								// [|기호]로 코드 줄일수있다
		} catch (InputMismatchException | ArithmeticException e) {
			System.out.println(e.toString());
		}
		
		System.out.println("END");
	}

}

> 예외 발생시키기 - throw

package days20;

public class Ex06 {

	public static void main(String[] args) {
		// p.425 예외 발생시키기 - throw (던지다)

		try {			
			//try~catch없으면 오류) java.lang.ArithmeticException: 강제로 예외발생
			throw new ArithmeticException("예외 메시지로 사용되는 값");	//throw 예외 객체;
		} catch (Exception e) {
			// private String message	-getter,setter
			System.out.println(e.getMessage());	//예외 메시지 출력
		}
		
		// Unreachable code 무조건 예외 발생시키니..
		//System.out.println("END");
		

	}

}
package days20;

import java.io.IOException;
import java.io.ObjectInputStream.GetField;

public class Ex07 {

	public static void main(String[] args) throws IOException {
		// p.427 메서드에 예외 선언하기
		// 예외처리 방법2 : 메서드() throws 예외클래스...
		
		/*
		throws IOException
		int one = System.in.read();	//Add throws declaration
		*/
		
		char one = '\0';
		one = getChar();
		// main에서도 메서드선언부에 throws 구문 추가해줘야함 (떠넘김)
	}

	private static char getChar() throws IOException {	//떠넘김
		System.out.print("> 한문자 입력 ? ");
		char one;
		one = (char) System.in.read();

		/* 안에서 알아서 처리
		try {
			one = (char) System.in.read();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		*/
		return 0;
	}

}

> 사용자 정의 예외 클래스

package days20;

/**
 * @author Hini
 * @date 2021. 4. 2 - 오후 2:19:40
 * @subject	사용자 정의 예외 클래스, throw 강제 예외발생 작업
 * @content	try~catch문 / throw문
 *
 */
public class Ex08 {

	public static void main(String[] args) {
		// p.427 ~ 434	그러나..
		// 메서드 선언할 때 메서드 내에서 발생할 가능성이 있는 예외를 
		// 메서드 선언부에 명시하여 메서드를 사용하는 쪽이 예외를 처리하도록 강요
		
		Score s = new Score();
		try { //try-catch 클릭
			s.setKor(110);
			System.out.println(s.getKor());
		} catch (ScoreOutOfBoundException e) {
			e.printStackTrace();
		}
		
		System.out.println("END");
		
	}

}//class

// 성적 처리 클래스
class Score{
	private int kor;

	public int getKor() {
		return kor;
	}

	public void setKor(int kor) throws ScoreOutOfBoundException {
		if (kor>=0 && kor<=100) {
			this.kor = kor;
		} else {	//내가 원하는 값이 아니면 예외를 발생시킴 근데 얼토당토않음
			//throw new ArithmeticException("국어 점수 잘못입력 (0~100)");
			throw new ScoreOutOfBoundException("국어 점수 잘못입력 (0~100)", 1008);
		}
	}
}


// 사용자 예외 클래스
class ScoreOutOfBoundException extends Exception{
	// 에러코드
	private final int ERR_CODE;

	public int getERR_CODE() {
		return ERR_CODE;
	}
	
	public ScoreOutOfBoundException() {
		this.ERR_CODE = 1001;
	}
	public ScoreOutOfBoundException(String message, int errCode) {
		super(message);
		this.ERR_CODE = errCode;
	}
	public ScoreOutOfBoundException(String message) {
		this(message, 1001);
	}
	
}

> 자동 자원 반환 (try-with-resources문)

package days20;

import java.util.Scanner;

public class Ex09 {

	public static void main(String[] args) {
		// p.436 자동 자원 반환 (try-with-resources문)
		
		
		/*
		// Resource leak: 'scanner' is never closed
		// 자원		누출		스캐너	닫히지 않았다
		Scanner scanner = new Scanner(System.in);
		System.out.print("> name  input ? ");
		String name = scanner.next();
		System.out.println(name);
		
		// 스캐너 사용 끝나면 닫아줘야함
		scanner.close();
		*/
		
		
		// 자동 자원 반환 (try-with-resources문)
		try (Scanner scanner = new Scanner(System.in)) {
			System.out.print("> name  input ? ");
			String name = scanner.next();
			System.out.println(name);
			// 스캐너 여기서만 사용되어지고 끝나면 자동으로 closed
		} catch (Exception e) {
			
		}
		
		
		
		
		
		
		
	}//main

}//class
Comments