[예외처리]예외, try~catch, finally, throws

EUNJI LEE·2023년 4월 12일
0

JAVA

목록 보기
8/12

예외처리(Exception)

프로그램 작성 중에 발견한 예외를 처리하는 방법을 말한다. 프로그램 오류(에러)는 소스 수정으로 해결 가능한 경우에 예외라고 부른다. 모든 예외 클래스는 Exception 클래스를 상속 받으며 반드시 예외처리 해야하는 Checked Exception런타임 중에 예외가 발생할 수 있는 Unchecked Exception으로 나뉜다. 일반 클래스처럼 기능을 따로 수행하는 것은 아니다.

에러의 종류

  1. 컴파일 에러
    프로그램 실행을 막는 문법 에러를 말한다. 에러가 발생한 구문을 수정해서 해결해야 실행할 수 있다. 런타임 전에 eclipse에서 빨간줄로 띄워주는 에러들은 컴파일 에러다.
  2. 런타임 에러
    런타임 에러는 실행 중에 생긴 에러로 주로 입력 값이 틀렸거나, 배열의 인덱스 범위를 벗어나는 경우가 많다. 주로 if문으로 에러가 발생할 예외들을 걸러내서 해결한다.
  3. 시스템 에러
    컴퓨터 오작동으로 인한 물리적인 에러로 소스 구문으로는 해결 불가능한 에러다.

RuntimeException 클래스

Unchecked Exception으로 주로 개발자의 부주의로 인한 오류인 경우가 많기 때문에 예외처리를 따로 지정하기 보다는 코드 자체를 수정하는 경우가 많다.

ArithmeticException

수학적으로 계산이 불가능할 때 발생하는 예외.
⚠️Exception in thread "main" java.lang.ArithmeticException: / by zero 0으로는 나누기를 할 수 없다는 에러 메시지가 뜬다.

int su=10;
int su2=0;
System.out.println(su/su2); //에러 발생

ArrayIndexOutOfBoundsException

인덱스 범위를 초과해서 접근할 때 발생하는 예외.
⚠️Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
인덱스5는 길이 5를 초과한다는 에러 메시지가 뜬다.

int[] intArr=new int[5];
System.out.println(intArr[5]); //에러 발생

ClassCastException

클래스 형변환을 잘못했을 때 발생하는 예외.
⚠️java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer

Object o=new String("안녕");
Integer num=(Integer)o; //에러 발생

NullPointException

참조형 변수에 null값이 있을 때 직접 접근 연산자를 사용하면 발생하는 예외.
⚠️java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null

String name=null;
name.length(); //에러 발생

NumberFormatException

문자열을 숫자형으로 변환할 때 변환 불가능한 문자가 있는 경우 발생하는 예외.
⚠️java.lang.NumberFormatException: Cannot parse null string
null을 int형으로 변환 불가능하다는 오류 메시지가 뜬다.

int su=0;
String name=null;
su=Integer.parseInt(name);

InputMissMatchException

입력값의 타입이 일치하지 않을 때 발생하는 예외.

Scanner sc=new Scanner(System.in);
su=sc.nextInt(); //int형 외에 문자열 등을 입력했을 때 에러 발생

try~catch

try ~ catch문을 이용해 직접 예외 처리를 할 수 있다. 예외가 발생할 구문이 있는 곳에서 try~catch문을 작성해서 예외 처리하면 되는데 try{예외 발생 가능성이 있는 구문} catch(발생 가능 예외) {예외 발생시 처리할 구문} 같은 방법으로 구문을 작성할 수 있다.

int[] intArr= {1,2,3,4,5};
try {
	int a=intArr[5];
	System.out.println(a);
}catch(ArrayIndexOutOfBoundsException e) {//()안은 매개변수처럼 선언
//길이가 안 맞아서 예외가 발생하면 길이를 늘려서 받을 수 있도록 처리 구문 작성
	int[] temp=new int[intArr.length+1];
	System.arraycopy(intArr, 0, temp, 0, intArr.length);
	intArr=temp;
	int a=intArr[5];
	System.out.println(a);
}
System.out.println("메소드 계속 실행"); //예외가 발생해도 출력된다.

💡 try~catch는 예외 처리를 하기 위해 작성하는 구문으로 예외가 발생해도 프로그램이 멈추지 않고 catch 구문을 실행 후 아래 로직을 이어서 실행한다.
또한, try문 안에서 예외가 발생하면 해당 시점에서 아래 구문은 무시하고 절차 진행되어 catch로 넘어간다.

✅ try~catch문도 마찬가지로 중괄호 { } 안에 선언한 내용은 해당 범위 안에서만 사용 가능하다.
Object o=new String("test");
try {
	int a=(int)o;
	o=intArr[11];
		}catch(ClassCastException e) {
			System.out.println("형변환 에러");
		}catch(Exception e) {
//어떤 오류던 똑같은 로직을 처리할 거라면 Exception으로 묶어서 예외처리 해도 된다.
			System.out.println(e.getMessage());
			System.out.println("예외처리");
		}

💡 모든 예외 클래스는 Exception 클래스를 상속 받기 때문에 catch() 안에 예외를 작성할 때도 부모 Exception을 적으면 자식 Exception이 발생했을 때 모두 처리할 수 있다.
때문에 catch문을 작성할 땐 예외 선언 순서에 주의해야 한다. 위에 catch문에 작성한 예외가 범위가 더 커서 이미 처리를 해버리면 아래 catch문은 실행될 일이 없기 때문이다.

finally

예외 처리 구문에서 반드시 실행 해야될 구문이 있는 경우 finally를 마지막에 작성해준다. 보통 파일 입,출력할 때 마지막에 닫아주기 위해서 사용한다. finallly는 예외 처리가 되든 안 되든 무조건 실행하는 구문으로 필수로 작성할 내용을 넣어준다.

Scanner sc=new Scanner(System.in);
try {
	String n=sc.next();
	n.length();
		}catch(NullPointerException e) {
			System.out.println("catch문");
			return;
		}finally { //return했어도 실행되고 예외처리에 포함이 안 되어있어도 실행한다.
			System.out.println("반드시 실행");
		}

throws

메소드를 선언 시 메소드 선언부에 throws ExceptionName을 추가해서 호출한 상위 메소드에게 처리를 위임하는 방식이다. 계속 추가로 위임이 가능하며 마지막까지 위임돼서 main()메소드에 가면 반드시 main메소드에서라도 처리를 해야한다. 처리되지 않는 경우 비정상적으로 종료한다.
예외 처리를 강제시키기 위해서 checkedException으로 많이 활용한다.

public void throwsTest() throws FileNotFoundException{
		FileInputStream fis=new FileInputStream("test.txt");
	} 
//해당 메소드를 호출한 곳에서는 FileNotFoundException에 대한 예외 처리를 해야한다.
profile
천천히 기록해보는 비비로그

0개의 댓글