예외 처리
예외 클래스들
-모든 예외 클래스의 최상위 클래스는 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);
}
}