[JAVA] 10. 예외처리

30606 단어 JavaJava

10.1 예외클래스

에러

컴퓨터의 고장으로 인해 프로그램 실행오류 발생

예외

게ㅐ발자의 잘못된 코딩으로 인해 프로그램 오류 발생(에러 외의 오류)

예외와 예외 클래스

일반 예외

컴파일러 체크 예외

컴파일하는 과정에서 해당 예외 처리 코드가 있는지 검사

java.lang.Exception 클래스 상속받음

실행 예외

컴파일러 넌 체크 예외

컴파일하는 과정에서 예외 처리 코드가 있는지 검사

java.lang.RuntimeException 클래스 상속받음

실행 예외

개발자가 처리해줘야 하는 예외 처리 코드

NullPointerException

객체 참조가 없는 상태에서 객체 사용하려 하면 발생하는 예외

null값을 갖는 참조 변수로 객체 접근 연산자인 도트를 사용했을 때 발생

package sec01.exam01;

public class NullPointerExceptionExample {
	public static void main(String[] args) {
		String data = null; // data는 String 객체를 참조하지 않음
		System.out.println(data.toString()); // toString()메소드 호출
	}
}

ArrayIndexOutOfBoundsException

인덱스 범위 초과할 경우 예외 발생

package sec01.exam02;

public class ArrayIndexOutOfBoundsExceptionExample {
	public static void main(String[] args) {
        // 2개의 실행값을 주지 않았기 때문에 args[0], args[1] 인덱스 사용 못함
		String data1 = args[0]; 
		String data2 = args[1];
		
		System.out.println("args[0]: " + data1);
		System.out.println("args[1]: " + data2);
	}
}

예외 발생하지 않게 수정

  • 이클립스 RUN - RUN Configuration -Arguments - Program arguments 에 2개의 매개값 입력하고 실행 (배열 , 인덱스 라고 입력을 줌)

  • 배열값을 읽기 전에 배열의 길이 먼저조사하여 매개값 없으면 조건문사용

package sec01.exam03;

public class ArrayIndexOutOfBoundsExceptionExample {
	public static void main(String[] args) {
		if(args.length == 2) {
			String data1 = args[0];
			String data2 = args[1];
			System.out.println("args[0]: " + data1);
			System.out.println("args[1]: " + data2);
		} else {
			System.out.println("두개의 실행 매개값이 필요합니다.");
		}
	}
}

NumberFormatException

숫자로 변환될 수 없는 문자가 포함되어 있을 떄 발생

package sec01.exam04;

public class NumberFormatExceptionExample {
	public static void main(String[] args) {
		String data1 = "100";
		String data2 = "a100";
				
		int value1 = Integer.parseInt(data1);
		int value2 = Integer.parseInt(data2); // NumberFormatException발생 
		
		int result = value1 + value2;
		System.out.println(data1 + "+" + data2 + "=" + result);
	}
}

ClassCastException

타입변환은 상위클래스-하위클래스, 인터페이스-구현클래스 간 발생하는데

이런 관계 아닐 때 예외 발생

package sec01.exam05;

public class ClassCastExceptionExample {
	public static void main(String[] args) {
		Dog dog = new Dog();
		changeDog(dog);
		
		Cat cat = new Cat();
		changeDog(cat);
	}
	
	public static void changeDog(Animal animal) {
		//if(animal instanceof Dog) {
			Dog dog = (Dog) animal; //ClassCastException 발생 가능
		//} 
        // 위에서 Cat객체를 매개값으로 주어서 Dog 타입으로 변환 불가, 주석처리풀어야 통과
        
	}
}

class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

10.2 예외 처리

예외처리

예외 발생했을 경우, 갑작스러운 종료를 막고, 정상 실행을 유지할 수 있도록 처리하는 것

예외처리 코드

try-catch-finally 블록

try : 예외 발생 가능 코드

catch : 예외 처리 코드

finally : 항상 실행

try 정상실행이면 catch 건너뛰고 finally실행

일반 예외 처리

ClassNotFoundException : 매개값으로 주어진 클래스가 존재하지 않을 때 발생

package sec01.exam06;

public class TryCatchFinallyExample {
	public static void main(String[] args) {
		try {
			Class clazz = Class.forName("String2");
		} catch(ClassNotFoundException e) { // String2 존재하지 않음
			System.out.println("클래스가 존재하지 않습니다.");
		}
	}
}

> 클래스가 존재하지 않습니다.
실행 예외 처리
package sec01.exam07;

public class TryCatchFinallyRuntimeExceptionExample {
	public static void main(String[] args) {
		String data1 = null;
		String data2 = null;
		try {
            // 실행 매개값을 주지 않아서 catch에서 예외 발생
			data1 = args[0];
			data2 = args[1];
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("실행 매개값의 수가 부족합니다.");
			return;
		} 
		
        // 여기서부터 2개의 실행값을 주게 되면 ('안녕', '하이')
		try { 
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			int result = value1 + value2;
			System.out.println(data1 + "+" + data2 + "=" + result);
		} catch(NumberFormatException e) { // 숫자로 바꿀수 없는 문자 예외 발생
			System.out.println("숫자로 변환할 수 없습니다.");
		} finally {
			System.out.println("다시 실행하세요.");
		}
	}
}

> 실행 매개값의 수가 부족합니다.
// 두번째 try문을 실행하기 위해 여기서는 2개의 실행값을 줌    
> 숫자로 변환할 수 없습니다.
> 다시 실행하세요.    

예외 종류에 따른 처리 코드

다중 catch

상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다.

상위 예외 클래스가 catch 블록이 위에 있다면, 하위 예외 클래스는 실행 안됨

하위는 상위를 상속했기 때문에 상위 예외 타입도 됙 때문이다.

package sec01.exam09;

public class CatchOrderExample {
	public static void main(String[] args) {
		try {
			String data1 = args[0];
			String data2 = args[1];
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			int result = value1 + value2;
			System.out.println(data1 + "+" + data2 + "=" + result);
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("실행 매개값의 수가 부족합니다.");
		} catch(Exception e) {
			System.out.println("실행에 문제가 있습니다.");
		} finally {
			System.out.println("다시 실행하세요.");
		}
	}
}

예외 떠넘기기

메소드에서 처리하지 않은 예외를 호출한 곳을 떠넘기는 역할

throws Exception만으로 모든 예외 떠넘길 수 있다

throws 키워드가 붙어있는 메소드는 반드시 try문 내에서 호출되어야 한다. & catch 블록에서 떠넘겨 받은 예외 처리해줘야한다

package sec01.exam10;

public class ThrowsExample {
	public static void main(String[] args) {
		try {
			findClass(); // try내에 호출한 메소드 존재해야
		} catch(ClassNotFoundException e) { // 떠넘겨 받은 예외 처리
			System.out.println("클래스가 존재하지 않습니다.");
		}
	}
	
	public static void findClass() throws ClassNotFoundException {
		Class clazz = Class.forName("java.lang.String2");
	}
}

main메소드에서 throws 키워드 사용해서 예외 떠넘기면 JVM이 처리

JVM은 콘솔에 예외 내용을 출력해줌

하지만 비선호하는 방법 -> TRY - CATCH 써라!

좋은 웹페이지 즐겨찾기