Java/패스트캠퍼스

예외 처리

hs_developer 2022. 6. 8. 01:43

예외 클래스들

 

-모든 예외 클래스의 최상위 클래스는 Exception 클래스

 

 

-자바에서는 다양한 예외들에 대해 그 처리를 위한 클래스를 제공한다.

 

 

 

 

-Arithmetic Exception: 정수를 0으로 나눈 경우 발생

 

-NullPointerException: 초기화 되지 않은 Object를 사용하는 경우

Dog d = null;
System.out.println(dog);

 

-ArrayIndexOutOfBoundsException: 배열의 크기를 넘어선 위치를 참조하는 경우

 

-FileNotFoundException: 참조하는 파일이 지정된 위치에 존재하지 않는 경우

 

-ClassNotFoundException: 클래스가 로드되지 않은 경우

 

-InterruptedException: Thread.sleep(), join(). Object의 wait()로 non-runnable 상태인 thread를 Runnable 하게 만들 수 있도록 할 수 있음

 

 

 

예외 처리하기와 미루기

try-catch문

 

-try 블럭에는 예외가 발생할 가능성이 있는 코드를 작성하고 try 블럭 안에서 예외가 발생하면 catch 블럭이 수행된다.

 

 

프로그래머가 예외를 처리해줘야 하는 예 (배열의 오류 처리)

1
2
3
4
5
Index 5 out of bounds for length 5
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
비정상 종료되지 않았습니다.
public class ArrayExceptionHandling {

	public static void main(String[] args) {
		
		int[] arr = {1, 2, 3, 4, 5};
		
		try
		{
			for(int i=0; i<=5; i++) // 0, 1, 2, 3, 4, 5
			{
				System.out.println(arr[i]);
			}
		} 
		catch(ArrayIndexOutOfBoundsException e) 
		{
			System.out.println(e.getMessage()); // Index 5 out of bounds for length 5
			System.out.println(e.toString()); 
			// java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
		}
		System.out.println("비정상 종료되지 않았습니다.");
	}
}

 

 

try-catch-finally문

-finally 블럭에서 파일을 닫거나 네트워크를 닫는 등의 리소스 해제 구현을 함

 

-try 블럭이 수행되는 경우, finally 블럭은 항상 수행 됨

 

-여러 개의 예외 블럭이 있는 경우 각각에서 리소스를 해제하지 않고 finally 블럭에서 해제하도록 구현 함

 

 

컴파일러에 의해 예외가 처리 되는 예 (파일 에러 처리)

 

java.io.FileNotFoundException: a.txt (지정된 파일을 찾을 수 없습니다)
항상 수행됩니다. - finally
여기도 수행됩니다. - 바깥구문
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileExceptionHandling {

	public static void main(String[] args) {
		
		FileInputStream fis = null;
		
		try 
		{
			fis = new FileInputStream("a.txt");
		} 
		catch(FileNotFoundException e) 
		{
			System.out.println(e);
		} 
		finally 
		{
			if(fis != null)
			{
				try
				{
					fis.close();
				}
				catch(IOException e)
				{
					e.printStackTrace();
				}
			}
			System.out.println("항상 수행됩니다. - finally");
		}
		System.out.println("여기도 수행됩니다. - 바깥구문");
	}
}

 

 

 

예외 처리 미루기

 

-예외 처리는 예외가 발생하는 문장에서 try-catch 블럭으로 처리하는 방법과 이를 사용하는 부분에서 처리하는 방법 두 가지가 있음

 

-throws를 이용하면 예외가 발생할 수 있는 부분을 사용하는 문장에서 예외를 처리할 수 있음

 

 

결과값은??

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ThrowsException {

	public Class loadClass(String fileName, String className) 
			throws FileNotFoundException, ClassNotFoundException
	{
		FileInputStream fis = new FileInputStream(fileName); // FileNotFoundException 발생
		Class c = Class.forName(className); // ClassNotFoundException 발생
		return c;
	}
	
	public static void main(String[] args) {
		
		ThrowsException test = new ThrowsException();
		
		try
		{
			test.loadClass("a.text", "java.lang.String");
		}
		catch(FileNotFoundException e)
		{ 
			e.printStackTrace();
		}
		catch(ClassNotFoundException e)
		{
			e.printStackTrace();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}

 

 

하나의 try 블럭에서 예외가 여러 개 발생하는 경우

 

 

-예외가 여러 개 발생하는 경우 예외를 묶어서 하나의 방법으로 처리할 수 있고

try
{
	test.loadClass("a.txt", "java.lang.String");
}
catch(FileNotFoundException | ClassNotFoundException e)
{
	e.printStackTrace();
}

 

 

-각각의 예외를 따로 처리할 수도 있음

try
{
	test.loadClass("a.txt", "java.lang.String");
}
catch(FileNotFoundException e)
{
	e.printStackTrace();
}
catch(ClassNotFoundException e)
{
	e.printStackTrace();
}
catch(Exception e)
{
	e.printStackTrace();
}

 

-Exception 클래스 활용해 default 처리를 할 때 Exception 블럭은 맨 마지막에 위치해야 함

 

 

 

사용자 정의 예외 클래스

 

비밀번호는 null일 수 없습니다.
비밀번호는 5자 이상이어야 합니다.
비밀번호는 숫자나 특수 문자를 포함해야 합니다.
오류 없음4
public class PasswordTest {

	private String password;
	
	public String getPassword()
	{
		return password;
	}
	
	public void setPassword(String password) throws PasswordException
	{
		if(password == null)
		{
			throw new PasswordException("비밀번호는 null일 수 없습니다.");
		}
		else if(password.length() < 5)
		{
			throw new PasswordException("비밀번호는 5자 이상이어야 합니다.");
		}
		else if(password.matches("[a-zA-Z]+"))
		{
			throw new PasswordException("비밀번호는 숫자나 특수 문자를 포함해야 합니다.");
		}
		
		this.password = password;
	}
	
	public static void main(String[] args) {
		
		PasswordTest test = new PasswordTest();
		
		String password = null;
		
		try
		{
			test.setPassword(password);
			System.out.println("오류 없음1");
		}
		catch(PasswordException e)
		{
			System.out.println(e.getMessage());
		}
		
		password = "abcd";
		
		try
		{
			test.setPassword(password);
			System.out.println("오류 없음2");
		}
		catch(PasswordException e)
		{
			System.out.println(e.getMessage());
		}
		
		password = "aaaaaa";
		
		try
		{
			test.setPassword(password);
			System.out.println("오류 없음3");
		}
		catch(PasswordException e)
		{
			System.out.println(e.getMessage());
		}
		
		password = "abcde#1";
		
		try
		{
			test.setPassword(password);
			System.out.println("오류 없음4");
		}
		catch(PasswordException e)
		{
			System.out.println(e.getMessage());
		}
	}
}
public class PasswordException extends IllegalArgumentException {

	public PasswordException(String message)
	{
		super(message);
	}
}