반응형

 

예외

 

: 잘못된 조작 또는 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다.

예외 처리 프로그램을 통해 실행상태를 유지할 수 있게 할 수 있으며 예외 처리 유무를 확인할 수 있다.

 

예외 클래스에서 여러가지의 예외를 클래스로 관리한다. 프로그램 실행 중 예외가 발생하면 해당 예외 클래스로 객체를 생성하고 예외 처리 코드에서 예외 객체를 이용할 수 있게 해준다.

예외 클래스에는 java.lang.Exception이 가장 큰 범위를 가지며 이후 일반 예외실행 예외로 나뉜다.

 

+ 에러 코드 읽는 방법

에러 코드 읽는 법 : 에러 코드가 길 경우 수정한 java 파일만 확인하면 된다.

 

 

 

일반 예외

= 컴퍼일러 체크 예외

 

: 자바 소스 컴파일 과정에서 예외 처리 코드가 있는지 검사한다.

 

예외 클래스 : 일반 예외, 실행 예외

 

 

 

실행 예외

= 컴파일러 넌 체크 예외

 

: 컴파일하는 과정에서 예외 코드를 검사하지 않는 예외를 말한다.

 

RuntimeException

 

package kr.or.ddit.study10;

import java.util.Scanner;

public class Exception01 {
	Scanner sc = new Scanner(System.in);
	public static void main(String[] args) {
		Exception01 e = new Exception01();
		e.process();
	}
	
	public void process() {
		int a = 10;
		int b = 0;
		// 런타임 Exception()
		// ArithmeticException 연산과 관련된 에러
		
		if(b == 0) { // if문과 같은 경우 개발자가 체크해줘야 함. 없을 시 에러 발생.
			System.out.println("0으로는 나눌 수 없습니다.");
			return;
		}
		System.out.println(a/b);
	}
}

 

결과 화면1 : if문이 없을 시 런타임 에러 발생.

 

 

= > 예외처리코드가 없을 경우 예외 발생 시 프로그램이 종료 되기에 개발자의 경험에 의해서 예외 처리 코드를 작성해야 한다.

 

 

 

NullPointerException

 

가장 빈번하게 발생하는 실행 예외.

객체 참조가 없는 상태(null 값)로 객체 접근 연산자인 도트(.)를 사용했을 때 발생한다.

 

 

 

ArrayIndexOutOfBoundsException

 

배열에서 인덱스 범위를 초과할 경우 발생하는 실행 예외.

 

package kr.or.ddit.study10;

import java.util.Scanner;

public class Exception01 {
	Scanner sc = new Scanner(System.in);
	public static void main(String[] args) {
		Exception01 e = new Exception01();
		e.process2();
	}
    
	public void process2() {
		int[] arr = new int[10];
		
		// 런타임 Exception()
		// java.lang.ArrayIndexOutOfBoundsException: 10
		// 배열 범위가 벗어날때 발생.
		int num = 10;
		
		try {
			for(int i=0; i<11; i++) {
				System.out.println(arr[i]);
				int sesult = num /arr[i]; // arr[i]가 0인 경우를 체크해주지 않으면 에러가 발생. 모든 것들을 전부 비교하기엔 무리가 있음 -> try 문 사용
			}
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("배열 범위가 잘못됨.");
		}
		catch (ArithmeticException e) {
			System.out.println("연산 에러 발생"); // 에러 발생시 타며 하단에 코드가 있을 시 그대로 진행됨.
		}
		
		//////////////////////////////////////////////////////////////
		
//		for(int i=-1; i<11; i++) {
//			System.out.println(arr[i]);
//			int sesult = num /arr[i];
//		}
		
		System.out.println("실행???");
		
	}
}

 

결과 화면2 : arr 배열의 값을 넣어준다면 이후 배열 범위가 잘못됨.이 출력된다.

 

=> 예외처리를 위해서 try - catch 문을 사용한다.

 

 

 

NumberFormatException

 

문자열을 숫자로 변환하는 경우 발생하는 예외.

숫자가 변환될 수 없는 문자가 포함된 경우 발생한다.

 

 

 

예외 처리 코드

 

예외 발생할 가능성이 있는 코드에서 작성하며 대표적으로 try-catch-finally 블록을 사용한다.

ex) try-catch-frinally 블록, throws 키워드

 

 

 

try-catch-finally 블록

 

: 생성자 및 메소드 내부에서 작성되며 일반예외와 실행예외가 발생할 경우 예외 처리를 가능하게 한다.

 

하단의 그림과 같은 식으로 진행되며 try 안에 있는 코드 중간에 예외 발생 시 이후 try 문 안에 있는 코드는 실행 시키지 않고 catch 문으로 이동된다.

 

catch문을 다중으로 사용 시 상위 클래스가 하위 클래스보다 아래위치해야 한다.

 

try-catch-finally 문

 

 

package kr.or.ddit.study10;

import java.util.Scanner;

public class Exception01 {
	Scanner sc = new Scanner(System.in);
	public static void main(String[] args) {
		Exception01 e = new Exception01();
		e.process3();
	}
    
	public void process3() {
		int a = 10;
		while(true) {
			try {
				System.out.println("숫자를 입력하세요.");
				int num = sc.nextInt();
				int result = a/num;
				break;
			} catch(ArithmeticException e) {
				System.out.println("0으론 나눌 수 없습니다.");
			}
			catch (Exception e) {
				System.out.println("숫자만 입력해주세요.");
			}
		}
		
//		System.out.println("실행1");
	}
}

 

결과 화면3 : 영어를 입력할 때는 숫자만 입력해 달라는 문구가 출력된다.

 

 

 

throws 키워드

 

: 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를 호출한 곳으로 넘기는 역할을 한다.

 

 

package kr.or.ddit.study10;

public class NicNameException extends RuntimeException{
	// Exception을 직접 만들 수 있음.
	public NicNameException() {
		super("부적절한 닉네임 입니다.");
	}
}

 

package kr.or.ddit.study10;

import java.util.Scanner;

public class Exception01 {
	Scanner sc = new Scanner(System.in);
	public static void main(String[] args) {
		Exception01 e = new Exception01();
		e.process4();
	}
	
	public void process4() {
		System.out.println("닉네임 입력");
		String name = sc.nextLine();
		
		try {
			if(name.contains("aa")) {
				throw new NicNameException();
			}
		} catch (NicNameException e) {
			System.out.println(e);
		}
	}
}

 

결과 화면4 : 다른 클래스로 직접 예외를 만들어 넣을 수 있다.

 

 

package kr.or.ddit.study10;

import java.util.Scanner;

public class Exception02 {
	Scanner sc = new Scanner(System.in);
	public static void main(String[] args) {
		
		/*
		 * throw 예외 강제 발생
		 * 	- 일반 메소드 내부에서 사용
		 * 	- 사용 형식
		 * 	  throw 예외 클래스 객체명
		 * 	  throw new Exception();
		 * 
		 * throws 예외 미루기
		 * 	- try ~ catch 블록을 예외 발생 가능성이 있는 명령문이 기술된 곳에서
		 *    처리하지 않고 해당 메소드를 호출하는 곳에서 예외처리를 강요할때 사용.
		 *    
		 *    메소드명() throws 예외클래스명
		 *    
		 *    위 메소드를 호출하는 명령문은 반드시 try catch 블록을 기술해야 하고
		 *    throws에 기술된 예외를 처리해야함.
		 */
		
		Exception02 e2 = new Exception02();
		e2.method1();
	}
	
	public void method1() {
		while(true) {
			try {
				String id = inputId();
				String pass = inputPass();
				System.out.println("id : " + id);
				System.out.println("pass : " + pass);
				break;
			} catch (Exception e) {
				System.out.println(e);
			}
		}
	}
	
	public String inputId() throws NicNameException{
		String id = sc.next();
		if(id.contains("aa")) {
			throw new NicNameException();
		}
		if(id.length() > 10) {
			throw new NicNameException();
		}
		
		return id;
	}
	
	public String inputPass() throws NicNameException{
		String pass = sc.next();
		if(pass.contains("aa")) {
			throw new NicNameException();
		}
		if(pass.length() > 10) {
			throw new NicNameException();
		}
		
		return pass;
	}
}

 

결과 화면5

 

결과 화면6 : 예외 처리가 발생하지 않을 때 출력화면

 

 

반응형