국비 16-2

냐아암·2023년 5월 9일
0

국비

목록 보기
22/114

프로그램 오류

프로그램 수행 시 치명적 상황이 발생하여 비정상 종료 상황이 발생한 것

  • 컴파일 오류: 프로그램 실행을 막는 소스 코드 상의 문법 오류(소스 코드 수정으로 해결)

  • 런타임 오류: 프로그램 실행 중 발생하는 오류(주로 if문 사용으로 오류 해결)

  • 시스템 오류: 컴퓨터 오작동으로 인한 오류(소스 코드 수정으로 해결 불가능)


예외(Exception)

소스 코드이 수정으로 해결 가능한 오류

  • Unchecked Exception: 선택적으로 예외처리
    RuntimeException과 자식 예외를 지칭
    프로그램 수행 중 개발자의 코딩 실수 또는 사용자의 잘못된 값 입력으로 흔하게 발생할 수 있는 예외
  • Checked Exception: 필수적으로 예외 처리
    RuntimeException과 자식 예외를 제외한 나머지 예외
    if문과 같은 단순 코드로 해결이 불가능하여 반드시 예외 처리 구문을 작성해야 하는 예외

  • try-catch 예외처리
    -try{}: 괄호 내부에 예외가 발생할 가능성이 있는 코드를 작성한 후 실행
    -catch(예외) {}: try 구문에서 발생한 예외를 잡아내 처리하여 프로그램이 비정상 종료되지 않도록 함

    cf. 발생하는 예외 중 일부 예외(대부분 Unchecked Exception)는 try-catch구문을 사용하지 않아도 예외 상황을 방지할 수 있다.

    cf. catch문 연속 작성 시 Exception(모든 예외의 최상위 부모) 상속 구조 주의(다형성)

  • try-catch-finally
    -finally: try 구문에서 예외가 발생하든 말든 무조건 마지막에 수행

  • throws: 호출한 메소드에게 예외를 던짐 -> 호출한 메소드에게 예외를 처리하라고 위임하는 행위

  • throw: 예외 강제 발생 구문(현재 메소드에 예외를 던짐)


-System.out.println(e.getClass()); //무슨 클래스에서 예외 발생했는지 알려줌

-System.out.println(e.getMessage()); //예외 발생 시 출력된 내용

-e.printStackTrace(); // 예외가 발생하기까지 모든 메소드 흐름을 출력


ExceptionTest

package edu.kh.exception.test;

import java.util.Scanner;

public class ExceptionTest {
	
	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		
		//컴파일 오류
		while(true) {
			System.out.print("정수 입력(0 입력 시 종료): ");
			int input = sc.nextInt();
			
//			int a = 99.9; //자료형이 맞지 않아 연산 불가능 -> 컴파일 오류
						  //코드로 수정 가능
						  //1) 변수 자료형을 double로 바꿔줌
						  //2) (int)99.9 강제 형변환
						  //4) 99.9 -> 99 또는 100으로 변경
			
			if(input ==0) {
				break;
			}
		}
		
		//런타임 오류 예제
		//런타임 오류: 프로그램 수행 중 발생하는 오류 -> 주로 if문으로 처리 가능
		
		int[] arr = new int[3]; //인덱스는 2까지
		
		arr[0] = 10;
		arr[1] = 20;
		arr[2] = 30;
		
		//java.lang.ArrayIndexOutOfBoundsException: 배열 범위 초과하는 오류 발생
		
		//해결
		if (arr.length >=3) { //배열의 인덱스 범위 초과 시
			System.out.println("배열의 범위를 초과했습니다.");
		}else {
			arr[3] = 40;
		}
		
		
	}

}

ExceptionService

package edu.kh.exception.model.service;

import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;

public class ExceptionService {

	// 예외(Exception): 소스 코드의 수정으로 해결 가능한 오류
	
	// 예외는 두 종류로 구분됨
	// 1) Unchecked Exception: 선택적으로 예외처리
	// 2) Checked Exception: 필수적으로 예외처리
	
	private Scanner sc = new Scanner(System.in);
	
	public void ex1() {
		
		//try - catch 에외처리
		//try {} : 괄호 내부에 예외가 발생할 가능성이 있는 코드를 작성한 후 실행
		//catch (예외) {}: try 구문에서 발생한 에외를 잡아내 처리하여
		//				  프로그램이 비정상 종료되지 않도록 함
		
		System.out.println("두 정수를 입력받아 나누기한 몫을 출력");
		
		System.out.print("정수1 입력: ");
		int input1 = sc.nextInt();
		
		System.out.print("정수2 입력: ");
		int input2 = sc.nextInt();
		
		/*
		try {
			System.out.println("결과: " + input1 / input2);
			//java.lang.ArithmeticException: / by zero
			//			산술적 예외: 0으로 나눌 수 없습니다.
		} catch(ArithmeticException e) { //e는 변수
			//try에서 던져진 예외를 catch문 매개변수로 잡음
			System.out.println("infinity"); //처리 코드
		}
		*/
		
		if (input2 != 0) {
			System.out.println("결과: " + input1 / input2);
		}else {
			System.out.println("infinity");
		}
		
		//발생하는 예외 중 일부 예외는 try - catch 구문을 사용하지 않아도
		//예외 상황을 방지할 수 있다.
		//(일부 예외 == 대부분의 UncheckedException)
		
		
		
		
		
	}
	
	public int inputNum() {
		
		
		int num=0;
		
		while(true) {
			
			try {
				System.out.print("정수를 입력하세요: ");
				
				num = sc.nextInt(); 
				//java.util.InputMismatchException: 잘못 입력 예외
				
				sc.nextLine(); //입력 버퍼 개행문자 제거
				
				break;
				
			}catch(InputMismatchException e) {
				System.out.println("잘못 입력하셨습니다. 정수만 입력해주세요.");
				sc.nextLine(); //버퍼에 남아있는 잘못 입력된 문자열 제거
			}
		}
		
		return num;
	}
	
	public void ex2() {
		
		//정수 3개를 입력받아 3개의 합계 구하기
		int sum =0;
		
		for(int i =0; i<3; i++) { //i = 0 1 2
			sum += inputNum();
		}
		
		System.out.println("합계 : "+ sum);
		
	}
	
	public void ex3() {
		
		//여러가지 예외에 대한 처리 방법
		
		try {
			System.out.print("입력 1: ");
			int num1 = sc.nextInt(); //InputMismatchException
			
			System.out.print("입력 2: ");
			int num2 = sc.nextInt(); //InputMismatchException
			
			System.out.println("나누기 결과: " + num1 / num2);
			//ArithmeticException
			//0으로 나눴을 때(num2==0), 정수가 아닌 것를 입력했을 때
			
			//*************************************************
			
			//강제로 NULLPointerException 발생
			// *NULLPointerException: 참조하지 않는 참조변수를 이용해서 코드를 수행할 때 발생
			String str = null;
			
			System.out.println(str.charAt(0));
			// NULLPointerException에 대한 예외처리가 없으면 오류 발생 후 종료
			
			
			//**************************************************
			//관계 없는 예외는 순서 관계 없이 catch문에 작성하면 된다.
			// == 밑의 경우에는 catch문끼리 순서 바꿔도 됨
			
		}catch(InputMismatchException e) {
			System.out.println("정수가 아닌 문자열이 입력되었습니다.");
		}catch(ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다.");
		}catch(Exception e /*부모 타입 참조 변수*/) {
			//예외처리 + 다형성
			//Exception 클래스: 모든 예외의 최상위 부모
			//다형성 - 업 캐스팅: 부모 타입 참조변수로 자식 객체를 참조
			System.out.println("예외가 발생해서 처리함");
			
			//** 상위 타입의 예외 클래스를 catch문에 작성하면
			//	 다형성 업 캐스팅에 의해서 모두 잡아서 처리 **
			
		}
		//*catch문 연속 작성 시 Exception 상속 구조를 주의하자(다형성)
		

	}
	
	public void ex4() {
		
		// 1) try - catch - finally
		// finally: try 구문에서 예외가 발생하든 말든 무조건 마지막에 수행
		
		
		try {
			
			System.out.println(4/0); // ArithmeticException 발생
			
		}catch(ArithmeticException e) {
			System.out.println("예외 처리됨");
			// 2) catch문 매개변수 활용
			// 매개변수 e: 예외 관련 정보 + 예외 관련 기능
			
			System.out.println(e.getClass()); //무슨 클래스에서 예외 발생했는지 알려줌
			//class java.lang.ArithmeticException
			System.out.println(e.getMessage()); //예외 발생 시 출력된 내용 
			// / by zero
			
			System.out.println(e); //e.toString()
			//java.lang.ArithmeticException: / by zero
			
			e.printStackTrace(); // 예외가 발생하기까지 모든 메소드 흐름을 출력
			//어디서 어떤 오류가 발생했는지 정확히 파악하는 용도
			
			
		}finally { //외부 프로그램(DB)과의 연결 끊기 시 주로 사용
			System.out.println("무조건 수행됨");
		}
		
		
		
	}
	
	//============================================================
	
	public void ex5() {
		
		// throws: 호출한 메소드에게 예외를 던짐
		//			-> 호출한 메소드에게 예외를 처리하라고 위임하는 행위
		
		// throw: 예외 강제 발생 구문(현재 메소드에 예외를 던짐)
		try {
			methodA();
			
		}catch(Exception e) {
			
			//Exception: 모든 예외의 최상위 부모
			//-> Exception이 catch 매개변수로 작성되었다. == 예외 종류 상관없이 모두 처리
			System.out.println("예외 처리됨");
			e.printStackTrace();
			//발생한 예외가 메소드와 위치에 대한 모든 내용 출력
			//- 예외 발생 지점 출력
		}
		

	}

	private void methodA() throws IOException{
		methodB();
	}

	private void methodB() throws IOException{
		methodC();
		
	}
	
	private void methodC() throws IOException { //throws~ 안 쓰면 오류(Checked Exception)
		//methodD() 메소드는 IOException을 발생시킬 가능성이 있으므로
		//호출하는 곳에서 예외처리를 반드시 해야 한다
		//단, UncheckedException은 선택적으로 예외처리 할 수 있음
		
		
		//IOException 예외 강제 발생
		throw new IOException();
		
		
		//발생한 예외를 처리하는 방법
		//1) try - catch로 감싸서 현재 위치에서 처리
		//2) throws로 호출한 메소드로 예외를 위임하여 처리
	}
	
	private void methodD() { //UncheckedException이기 때문에 throws~같은 예외처리 구문 굳이 작성 안 해도 OK
		
		throw new RuntimeException();
		
		//CheckedException:
		// - RuntimeException과 자식 예외를 제외한 나머지 예외
		//	 if문과 같은 단순 코드로 해결이 불가능하여
		//	 반드시 예외 처리 구문을 작성해야 하는 예외
		
		//UncheckedException:
		// - RuntimeException과 자식 예외를 지칭
		//	 프로그램 수행 중
		//	 개발자의 코딩 실수 또는 사용자의 잘못된 값 입력으로
		//	 흔하게 발생할 수 있는 예외
		
		//--> 예외 처리 구문이 아니라 if문 같은 단순 코드로 해결 가능
		//--> 예외 처리 구문을 반드시 작성할 필요는 없음
		
	}
}

ExceptionRun

package edu.kh.exception.run;

import edu.kh.exception.model.service.ExceptionService;

public class ExceptionRun {

	public static void main(String[] args) {
		
		ExceptionService service = new ExceptionService();

//		service.ex1();
//		service.ex2();
//		service.ex3();
//		service.ex4();
		service.ex5();
		
	}

}
profile
개발 일지

0개의 댓글