220619_인터넷 강의_예외 처리

창고·2022년 10월 21일
0

티스토리에 저장했던 글을 옮겼습니다.
https://mrcocoball.tistory.com/92

1. 예외 처리의 중요성

  • 프로그램의 비정상 종료를 회피, 시스팀이 원활하게 실행되게끔
  • 오류 발생 시 log를 남겨 log 분석을 통해 원인을 파악, 버그를 수정

(1) 프로그램에서의 오류

  • 컴파일 오류 (Compile Error)
    • 프로그램 코드 작성 중 발생하는 문법적 오류
    • 최근에는 개발 환경에서 대부분의 컴파일 오류는 탐색됨
  • 실행 오류 (Runtime Error)
    • 실행 중인 프로그램이 의도 하지 않은 동작(bug)을 하거나 프로그램이 중지 되는 오류
    • 실행 오류는 비정상 종료가 되는 경우 시스템의 심각한 장애를 발생할 수 있음

(2) 오류와 예외 클래스

  • 시스템 오류 (Error) 와 예외 (Exception)은 모두 Throwable을 상속하고 있음
  • Java는 대부분 프로그램에서 발생하는 오류에 대해 문법적으로 예외 처리가 필요
  • 모든 예외 클래스의 최상위 클래스 : Exception 클래스

2. 예외 처리하기

(1) try-catch 문

  • try 블록에 예외 발생할 수 있는 코드 작성, try 블록 내에서 예외 발생 시 catch 블록 수행
try {

  예외 발생할 수 있는 부분

} catch (예외 타입 e) {

 예외 발생 시 예외를 처리하는 부분

}
public class ArrayExceptionHandling {

	public static void main(String[] args) {
		int[] arr = {1,2,3,4,5};
		try {
			for (int i=0; i<=5; i++) {
				System.out.println(arr[i]);				
			} 
		}catch(ArrayIndexOutOfBoundsException e) {
				System.out.println(e.getMessage());
				System.out.println(e.toString());
		}
		
		System.out.println("정상 수행 완료");

	}

}

(2) try-catch-finally 문

  • finally 블록에서 파일을 닫거나 네트워크를 닫는 등의 리소스 해제 구현
  • try 블럭 수행 시 finally 블럭은 항상 수행 됨
  • 여러 개의 예외 블럭이 있을 경우 리소스를 해제하지 않고 finally 블록에서 해제하도록 구현됨
public class FileExceptionHandling2 {

	public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("a.txt");
			System.out.println("read");
			
		} catch (FileNotFoundException e) {
			System.out.println(e);
			return;
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			System.out.println("finally");
		}
		System.out.println("처리 완료");
	}

}

(3) try-with-resource 문

  • 리소스 사용 시 close() 하지 않아도 자동으로 해제됨
  • 리소스를 try() 내부에서 선언해야 함
  • close()를 명시적으로 호출하지 않아도 try 블록에서 열린 리소스는 정상적인 경우나 예외 발생 경우 모두 자동으로 해제
  • 해당 리소스 클래스가 AutoCloseable 인터페이스를 구현해야 함
public class AutoCloseableObj implements AutoCloseable{
	
	@Override
	public void close() throws Exception {
		System.out.println("Closing......");
	}

}
public class AutoCloseTest {

	public static void main(String[] args) {
		
		AutoCloseableObj obj = new AutoCloseableObj();
		
		try(obj) {
			throw new Exception();
			
		} catch (Exception e) {
			System.out.println("Exception");
		}
		
		System.out.println("End");

	}

}
public class FileExceptionHandling {

	public static void main(String[] args) {
		// FileInputStream fis = null;
		try(FileInputStream fis = new FileInputStream("a.txt")) {
			System.out.println("read");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		System.out.println("처리 완료");
	}

}

3. 예외 처리 미루기

  • throws 사용 시 예외가 발생할 수 있는 부분을 사용하는 문장에서 예외 처리 할 수 있음
public class ThrowException {
	
	public Class loadClass(String fileName, String className) throws ClassNotFoundException, FileNotFoundException {
		// 예외 처리를 loadClass로 넘기겠다는 뜻
		
		FileInputStream fis = new FileInputStream(fileName);
		Class c = Class.forName(className);
		return c;
		
	}

	public static void main(String[] args) {
		
		ThrowException test = new ThrowException();
		
		try {
			test.loadClass("a.txt", "abc");
		} catch (ClassNotFoundException e) {
			System.out.println(e);
		} catch (FileNotFoundException e) {
			System.out.println(e);
		/* } catch (FileNotFoundException | ClassNotFoundException e) {
			System.out.println(e); */ // 한번에 처리
		} catch (Exception e) {
			System.out.println(e);			
		}
		
		System.out.println("end");
	}

}

4. 예외가 여러 개 발생할 경우

(1) 예외를 묶어서 하나의 방법으로 처리

		/* } catch (FileNotFoundException | ClassNotFoundException e) {
			System.out.println(e); */ // 한번에 처리

(2) 각각의 예외를 따로 처리

		ThrowException test = new ThrowException();
		
		try {
			test.loadClass("a.txt", "abc");
		} catch (ClassNotFoundException e) {
			System.out.println(e);
		} catch (FileNotFoundException e) {
			System.out.println(e);
		/* } catch (FileNotFoundException | ClassNotFoundException e) {
			System.out.println(e); */ // 한번에 처리
		} catch (Exception e) {
			System.out.println(e);			
		}
		
		System.out.println("end");
	}

(3) Exception 클래스를 활용, 기본 예외 처리 시 Exception 블록은 항상 맨 마지막에 위치하여야 함

  • 모든 예외의 최상위이므로 정확한 예외 원인을 찾기 위해서는 맨 마지막에 놓아야 함

5. 사용자 정의 예외 클래스

(1) 사용자 정의 예외 클래스 구현

  • 프로그래머가 직접 만들어야 하는 예외가 많음
  • 기존 예외 클래스 중 가장 유사한 예외 클래스에서 상속 받아 사용자 정의 예외 클래스를 구현
  • 혹은, Exception 클래스를 상속해서 구현

(2) 예제 : 패스워드에 대한 예외 처리

public class PasswordException extends Exception {
	
	public PasswordException(String message) {
		super(message);
	}

}
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 = "abcde";
		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());
		}


	}

}

6. 오류의 로그 남기기

  • 오류 발생 시 오류에 대한 기록을 남겨 디버깅을 용이하게 해야 함
  • 오류 외에 로그 파일에 기록하는 코드를 추가, 필요한 정보가 로그로 남을 수 있도록 처리해야 함
  • 디버깅, 시스템 에러 추적, 성능, 문제점 향상 등을 위해 사용
  • 자바에서는 기본적으로 java.util.logging 로그 패키지를 제공
  • 오픈소스로는 log4j를 많이 사용
  • 로그 레벨이 상이함 (severe, warning, info, config, fine, finest 등...)
profile
공부했던 내용들을 모아둔 창고입니다.

0개의 댓글