본문 바로가기
프로그래밍 언어/자바

예외 처리

by 블루데이제이 2022. 9. 12.
728x90
반응형

예외 처리

프로그램에서 예외 처리는 안정적인 프로그램을 만들기 위해서입니다. 그러나 빌게이츠든 스티브 잡스든 100% 완벽한 프로그램은 못 만듭니다.

예외는 오류보다는 정상적인 프로그램의 처리를 벗어난 잘못된 동작이라고 할 수 있습니다.

예외가 발생했다면 최소한의 일을 처리할 수 있어야 합니다.

☞ 어떤 이유로 오류가 발생했는 지 사용자에게 알려주어야 합니다.(꼭 그렇지만도 않음. 공공프로젝트에서 오류코드와 오류명을 화면에 표시하면 보안상의 문제가 있다고 표시 못하게 하는 경우도 있음)

☞ 어떤 데이터를 다루는 중이었다면 모든 데이터를 저장해합니다.(가능할지 모르겠어요)

☞ 최악의 경우 안전한 방법으로 프로그램을 종료할 수 있어야 합니다.

예외 타입

프로그램에서 오류를 모두 처리해 줄 수 있는 것은 아닙니다. 예측이 가능해서 예외 처리를 해줄 수 있는 오류가 있고 전혀 예측불가한 것에 대한 오류는 조치를 취할 수 없는 것들이 있습니다.

시스템 오류와 같은 것은 프로그래머가 어찌할 수 없더라도 0으로 나누면 오류가 나는 것을 예측할 수 있어서 대처가 가능합니다. 이렇게 처리할 수 있는 오류를 자바에서는 Exception이라고 합니다.

 

실행시간 오류

실행시간 오류(Runtime Exception)는 프로그램 실행 도중 발생하는 예외로 프로그램 컴파일 시점에서 알아낼 수 없습니다. 대부분의 실행시간 오류는 프로그래머의 잘못으로 발생하는 경우가 많습니다.

String[] arrStr = {"A", "B", "C"};
System.out.println(arrStr[0]); //A 정상출력
System.out.println(arrStr[1]); //B 정상출력
System.out.println(arrStr[2]); //C 정상출력
System.out.println(arrStr[3]); //오류 발생

■ 대표적인 Runtime Exception 종류

- NullPointer Exception : null객체를 참조하는 경우

- ClassCastException : 클래스의 형 변환을 잘못했을 경우

- IndexOfBoundsException : 배열 등에서 범위를 벗어난 index를 사용할 경우

- ArithmeticException : 수치 계산 오류

 

입출력 오류

입출력 오류(IOException)는 예외가 발생할 시점과 종류를 알수 있기 때문에 이 예외에 대한 처리를 반드시 해주어야 합니다.

예외가 발생할 확률이 높은 것을 컴파일할 때 알아내어 잉 대한 처리를 해줄 수 있는 예외가 바로 IOException입니다.

예외 처리 해결

자바에서는 예외는 try ~ catch블록을 사용하여 처리합니다.

try{
    예외가 발생할 가능성이 있는 코드
}catch(예외종류1){
    예외처리
}catch(예외종류2){
    예외처리
}
RuntimeExcetion 처리
package com.bluedayj;

import java.util.Vector;

public class RExceptionTest {
	public static void main(String[] args) {
		Vector v = new Vector();
		v.add("객체1");
		v.add("객체2");
		v.add(3);
		v.add("객체3");
		
		for(int i = 0; i < v.size(); i++) {
			String name = (String) v.elementAt(i);
			System.out.println(name);
		}	
		System.out.println("프로그램 정상 종료");
	}
}

위 소스 코드를 실행하면 ClassCastException 오류가 발생하고 프로그램이 정상 종료되지 않습니다.

벡터 객체의 내용과 상관없이 모두 String으로 형변환을 하고 있습니다.

벡터에는 String 뿐만 아니라 Integer 형이 포함되어 있어서 형변환 오류가 발생한 것입니다.

package com.bluedayj;

import java.util.Vector;

public class RExceptionTest {
	public static void main(String[] args) {
		Vector v = new Vector();
		v.add("객체1");
		v.add("객체2");
		v.add(3);
		v.add("객체3");
		
		for(int i = 0; i < v.size(); i++) {
			try {				
				String name = (String) v.elementAt(i);
				System.out.println(name);
				
			}catch(NullPointerException e) {
				System.out.println("예외 정보1 : ");
				e.printStackTrace();
			}catch(ClassCastException e) {
				System.out.println("예외 정보2 : ");
				e.printStackTrace();
			}
		}	
		System.out.println("프로그램 정상 종료");
	}
}

위 소스 코드를 수정하고 다시 실행해 봅니다.

예외 처리없이 실행하면 오류가 발생할 경우에는 프로그램 정상 종료 되지 않지만 예외 처리 시 프로그램이 정상 종료되는 것을 볼 수 있습니다.

IOException 처리
package com.bluedayj;

import java.net.URL;

public class IOExceptionTest {
	public static void main(String[] args) {
		URL url = new URL("http://www.daum.net");
		System.out.println("프로토콜 : " + url.getProtocol());
	}
}

위 소스 코드를 실행하면 오류가 발생합니다.

RuntimeException오류는 실행시 발생하지만 IOException은 컴파일시 예외의 발생 여부를 알 수 있습니다.


package com.bluedayj;

import java.net.MalformedURLException;
import java.net.URL;

public class IOExceptionTest {
	public static void main(String[] args) {
		URL url;
		try {
			url = new URL("http://www.daum.net");
			System.out.println("프로토콜 : " + url.getProtocol());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
}

try - catch - finally

finally 블록은 try - catch 블록내의 코드가 예외를 발생하는 것에 상관없이 무조건 실행됩니다.

package com.bluedayj;

public class FinallyTest {
	public static void main(String[] args) {		
		try {
			String str = null;
			str.substring(5);
			System.out.println("정상코드1");
		}catch(NullPointerException e) {
			System.out.println("예외1");			
		}finally {
			System.out.println("finally1");
		}
		
		try {
			System.out.println("정상코드2");
		}catch(Exception e) {
			System.out.println("에외2");
		}finally {
			System.out.println("finally2");
		}
	}
}

예외 상황 회피

만일 메소드나 생성자에서 IOException 발생 가능성이 있으면 예외 처리를 반드시 해주어야 했습니다. 그런데 이 예외 상황을 회피할 수 있습니다. 메소드를 호출하는 부분에서 이 예외 상황을 대신 처리할 수 있도록 하는 것입니다.

package com.bluedayj;

import java.net.URL;

public class ThrowsTest {
	public ThrowsTest() {
		callUrl();
	}
	
	public void callUrl() {
		URL url = new URL("http://www.daum.net");
		System.out.println(url.getHost());
	}
	
	public static void main(String[] args) {
		new ThrowsTest();
	}
}

위 소스 코드에서 callUrl 메소드에서 IOException처리를 하지 않아서 오류가 발생합니다.

callUrl 메소드에서 예외 처리를 하지 않고 callUrl 메소드를 호출하는 ThrowsTest메소드에 떠넘길 수 있습니다. 메소드 선언부에 throws문을 사용하여 이 메소드 내부에서 처리해야 하는 예외의 이름을 적어주기만 하면 됩니다.

package com.bluedayj;

import java.net.MalformedURLException;
import java.net.URL;

public class ThrowsTest {
	public ThrowsTest() {
		try {
			callUrl();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
	
	public void callUrl() throws MalformedURLException {
		URL url = new URL("http://www.daum.net");
		System.out.println(url.getHost());
	}
	
	public static void main(String[] args) {
		new ThrowsTest();
	}
}

728x90
반응형

'프로그래밍 언어 > 자바' 카테고리의 다른 글

AWT - GUI 프로그래밍 #2 Label  (0) 2022.09.12
AWT - GUI 프로그래밍 #1  (0) 2022.09.12
날짜 다루기  (0) 2022.09.12
벡터와 해시테이블  (0) 2022.09.12
자바 문자열 다루기 #2  (0) 2022.09.12