예외(Exception)

전영덕·2023년 2월 2일
0

Java Study

목록 보기
32/36
post-custom-banner

1. Error의 종류

  • 컴파일 에러
    .java -> .class 로 JVM이 컴파일을 하려고하는데 컴파일 자체가 안되는 에러.
    소스코드의 구문 오류로 인하여 컴파일이 불가능한 상태.
    이클립스에서 빨간색으로 표시되는 경우에 해당한다.
    프로그램을 실행하기 전에 발견되므로 상대적으로 수정하기 쉽다.

  • 런타임 에러
    구문 상의 에러는 없지만 프로그램이 실행되는 과정에서 다양한 경우의 수에 대흥하지 못하여 발생하는 예외상황.
    런타임 에러가 발생하면 프로그램은 강제로 종료된다.
    우리가 프로그램의 에러라고 부르는 현상은 대부분 런타임에러에 해당한다.

2. 런타임 에러의 종류

  • 런타임 에러에는 프로그램 자체의 구조적인 문제로 인한 논리적 오류와 자바 가상 머신 자체의 문제로 인한 오류, 그리고 예외가 있다.
  • 논리오류 : 논리적 모순이 생기지 않도록 코드 작성.
  • 자바 가상 머신 자체 오류 : 프로그래머가 책임질 수 있는 수준의 오류가 아니다.
  • 예외(Exception) : 프로그램 실행 중에 발생할 수 있는 예기치 않은 사건으로, 프로그래머의 노력으로 처리할 수 있다.
    자바 가상 머신은 프로그램 실행 중에 예외가 발생하면 관련된 예외 클래스로부터 예외객체를 생성하여 프로그램 지정된 예외 처리 구문으로 넘긴다.
  • 예외가 발생하면 프로그램에 지정된 예외 처리 구문이 자바 가성머신에 의해 호출되고, 이 때 전달되는 예외 객체를 넘겨받아 적절한 처리를 수행한다.
  • 자주접하게 되는 예외 상황

    사진에 있는 것이 다가 아니고 외울필요없이 자주 나오는 것들만 기억해두자

예를 들어 : nullPointerException : NULL객체 참조시 발생

  • 예외 클래스의 이름과 이름이 상관이 있다.

2-3. Java의 예외처리

  • java에서는 try~catch~finally 구문을 통해 프로그래머가 예외 상황에 대응할 수 있도록 하고 있다.

try{
//기본적으로 실행되는 구문
} catch( 예외클래스이름 객체이름){
//try 블록에서 예외가 발생한 경우 이곳으로 제어가 넘어온다

} finally{ //예외상황의 발생 여부에 상관없이 무조건 실행되는 구분
//finally 부분은 생략이 가능하다.
}

  • try블록 실행중 catch에서 명시한 예외 클레스에 해당하는 런타임 에러가 발생하면 try 블록을 즉시 중단하고 catch블록이 실행된 후, finally블록이 실행된다.
  • 예외가 발생하지 않을 경우에는 try블록 종료 후 finally블록이 실행된다.

2. 에러 객체'e'

  • e.printStackTrace();
    실제 외상황시에 출력되는 메시지를 강제로 출력한다.
    개발자가 catch블록 안에서 예외 상황을 분석하기 위한 용도로 사용한다.

  • e.getMessage();
    간략한 에러 메시지를 리턴한다.

5. Exception 이해하기

  • catch블록을 사용한 복합 에러 처리 : catch블록은 에러가 예상되는 상황에 대해 복수로 명시하는 것이 가능하다.
    try안에 에러가 여러 개일 경우: try안을 위에서 부터 아래로 내려오면서 하나씩 오류를 잡아냄

6. Exception 클래스

  • java에서 예외 상황을 의미하는 모든 클래스들의 최상위 클래스

  • 이 클래스의 이름으로 catch 블록을 구성하면 모든 예외 상황에서 일괄적으로 대응할 수는 있지만, catch블록이 세분화된 경우와는 달리 상황별 개별적인 처리는 불가능하다.

  • Exception 클래스에 대한 예외처리는 대부분 맨 마지막에 catch블록에 명시하여 '마지막 알 수 없는 에러' 를 의미하도록 구성한다.

  • 세분화클래스를 사용하는 경우와 최상위클래스만 사용하는 경우가 각각있음
    옛날엔 ID , PW에 대해 각각 뭐가 서버에 저장된 정보와 다른지 알려줬었음. 즉, 뭘 틀렸는지를 각각 로그인 시도하는 유저에게 정보를 제공해야하니까 세분화된 클래스를 사용했었음.
    하지만 개인 정보 보호법이 바뀌어서 이제는 안 알려줌. 그래서 요즘은 최상위 클래스만 써도 괜찮음

  • 세분화된 클래스를 사용 하는 경우에도 마지막에는 최상위클래스도 써줘야 나머지 에러도 잡을수 있음.

  • 실습 - String타입의 int변환 에러

package exception;
public class Main01 {
	public static void main(String[] args) {
    
		String year = "1980";
		int age1 = 2023 - Integer.parseInt(year);
		System.out.println(age1);
		// 문자열의 숫자 변환에는 아무런 문제가 없다.(parseInt사용!)
        
		String year2 = "나이";
		int age2 = 2023 - Integer.parseInt(year2);
		System.out.println(age2);
        // - "나이"라는 String은 int 로 변환할 수 없기 때문에 에러가 발생한다.
		// - 자바프로그램은 예외상황을 만나면 그 즉시 프로그램을 중단하고 강제종료된다.
		// 마지막 "---프로그램 종료---" 또한 출력되지 않는다. 위에 1980은 출력된다.
		
		System.out.println("---프로그램 종료---");
	}
}
  • 실습 - 배열에서 데이터 초과 에러
package exception;

public class Main02 {

	public static void main(String[] args) {

//크기가 3인 배열을 0부터 5까지 반복하면서 데이터를 저장한다. 배열의 크기가 3이므로
//배열 인덱스는 0~2까지로 제한되기 때문에 i의 값이 3이 되었을때 에러가 발생한다.

		int[] arr = new int[3];

		for (int i = 0; i < 5; i++) {
			arr[i] = i;
			System.out.println(arr[i]);
		}
	}

여기에서 예외를 처리하는 고전적인 방법.

package exception;
public class Main03 {
	public static void main(String[] args) {

		int[] arr = new int[3];
		for (int i = 0; i < 5; i++) {
	// 프로그램이 논리적 모순에 빠지지않도록 프로그래머가 if문을 사용하여 처리해 준다.
    //애초에 숫자 5를 arr.length()로해도 된다.
			if (i < arr.length) {
				arr[i] = i;
				System.out.println(arr[i]);
			}
		}
	}
}
  • try~catch~finally 구문연습
package exception;
public class Main04 {
	public static void main(String[] args) {
		try {
				String year2 = "나이";
				int age2 = 2023 - Integer.parseInt(year2);
			System.out.println(age2);
			} catch (NumberFormatException e) { 
        // catch소괄호부분은 메서드처럼 활용, 파라미터로 보통e를 사용함
					System.out.println("Error발생");
					System.out.println("원인 :"+ e.getMessage());
					e.printStackTrace();
					}
		System.out.println();
		System.out.println("---프로그램 종료---");
	}
}
  • try~catch~finally 구문연습에서 에러가 복수인 경우
package exception;
public class Main05 {
	public static void main(String[] args) {
		
		try {
			String year2 = "10";
			int age2 = 2023 - Integer.parseInt(year2);
			System.out.println(age2);
			
			int[] arr = new int[3];
			for (int i = 0; i < 5; i++) {
					arr[i] = i;
					System.out.println(arr[i]);
			}
		}catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("에러발생");
			System.out.println("원인 : " + e.getMessage());
		}catch(NumberFormatException e) {
			System.out.println("에러발생");
			System.out.println("원인 : " + e.getMessage());
		}catch(Exception e) {
			System.out.println("알 수 없는 에러 발생");
			System.out.println(e.getMessage());
		}
				System.out.println("---프로그램을 종료합니다---");
	}

}
  • Exception 처리연습
    예외의 발생 여부의 상관없이 "데이터 변환 종료"라는 문구 출력
    여러가지 사용자가 입력할테니 바꿔가면서 해보는데 데이터변환 종료는 꼭 나와야함.
package exception;
public class Main06 {
	public static void main(String[] args) {
		

		// 시용자가 입력한 값
		String[] src = {  "2", "3232", "1231" };
		int[] arr = new int[3];
		
		// src의 내용들을 숫자로 변환해서 저장할 배열
			try {
				for (int i = 0; i < src.length; i++) {
					arr[i] = Integer.parseInt(src[i]);
				}
				
		} 	catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("데이터가 너무 많습니다");
			System.out.println("원인 : " + e.getMessage());
			e.printStackTrace();
			
		}	catch(NumberFormatException e) {
			System.out.println("입력값에 오류가 있습니다");
			System.out.println("원인 : " + e.getMessage());
            e.printStackTrace();
		}	catch (Exception e) {
			System.out.println("에러 발생");
			//System.out.println("에러 원인 : "+ e.getMessage());
			e.printStackTrace();
		}	finally {
			System.out.println("데이터 변환 종료");//이 블록은 예외의 발생 여부에 상관없이 무조건 실행된다.
		}
			System.out.println("---프로그램을 종료합니다---");
	}
}
post-custom-banner

0개의 댓글