
⏩ 에러(error) : 컴퓨터 하드웨어의 고장으로 인해 응용프로그램 실행 오류 발생
⏩ 예외(exception) : 잘못된 사용 또는 코딩으로 인한 오류
에러나 예외 둘 다 발생하면 프로그램이 곧바로 종료됨. 다만, 예외는 예외 처리를 통해 계속 실행 상태를 유지할 수 있음
자바는 예외가 발생하면, 예외 클래스로부터 객체를 생성한다. 객체는 예외 처리할 때 사용된다.
자바의 모든 에러와 예외 클래스는 Throwable을 상속받아 만들어지고, 추가적으로 예외 클래스는 java.lang.Exception 클래스를 상속받는다
실행 예외는 RuntimeException과 그 자식 클래스에 해당
try - catch - finally 블록으로 구성
public class ExceptionHandlingExample2 {
public static void printLength(String data) {
try {
int result = data.length();
System.out.println("문자 수: " + result);
} catch(NullPointerException e) {
System.out.println(e.getMessage()); //①
//System.out.println(e.toString()); //②
//e.printStackTrace(); //③
} finally {
System.out.println("[마무리 실행]\n");
}
}
public static void main(String[] args) {
System.out.println("[프로그램 시작]\n");
printLength("ThisIsJava");
printLength(null);
System.out.println("[프로그램 종료]");
}
}
다중 catch를 사용해 발생하는 예외에 따라 다양한 예외들을 예외 처리 코드로 다르게 작성할 수 있다.
try {
int value = Integer.parseInt(array[i]);
System.out.println("array[" + i + "]: " + value);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("배열 인덱스가 초과됨: " + e.getMessage());
} catch(NumberFormatException e) {
System.out.println("숫자로 변환할 수 없음: " + e.getMessage());
}
try {
int value = Integer.parseInt(array[i]);
System.out.println("array[" + i + "]: " + value);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("배열 인덱스가 초과됨: " + e.getMessage());
} catch(Exception e) {
System.out.println("실행에 문제가 있습니다.");
}
try {
int value = Integer.parseInt(array[i]);
System.out.println("array[" + i + "]: " + value);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("배열 인덱스가 초과됨: " + e.getMessage());
} catch(NullPointerException | NumberFormatException e) {
System.out.println("데이터에 문제가 있음: " + e.getMessage());
}
FileInputStream fis = null;
try {
fis = new FileInputStream("file.txt"); //파일 열기
}catch(IOException e){
} finally{
fis.close(); //파일 닫기
}
public class FileInputStream implements AutoCloseable{
@override
public void close() throws Exceptions {...}
}
try(FileInputStream fis = new FileInputStream("file.txt")){
} catch(IOException e){
}
try-with-resources를 이용해 하면 더 간단하다. try 괄호에 리소스를 여는 코드를 작성하는 것이다.
메소드 내부에서 예외가 발생할 때 try-catch 블록으로 처리하는 게 일반적이지만, 메소드를 호출한 곳으로 throws를 사용해 예외를 떠넘길 수 있다.
public class ThrowsExample1 {
public static void main(String[] args) {
try {
findClass();
} catch(ClassNotFoundException e) { //호출한 곳에서 예외처리
System.out.println("예외 처리: " + e.toString());
}
}
public static void findClass() throws ClassNotFoundException {
Class.forName("java.lang.String2");
}
}
public class ThrowsExample2 {
public static void main(String[] args) throws Exception {
findClass();
}
public static void findClass() throws ClassNotFoundException {
Class.forName("java.lang.String2");
}
}
나열할 예외 클래스가 많으면 throws Exception 또는 throws Throwable 만으로 모든 예외를 간단히 떠넘길 수 있다.
일반 예외, 실행 예외 선언 둘 다 가능하다
일반 예외는 Exception의 자식 클래스로 선언, 실행 예외는 RuntimeException의 자식 클래스로 선언
public class InsufficientException extends Exception { //일반 예외로 선언
public InsufficientException() {
}
public InsufficientException(String message) { //두 개의 생성자 선언
super(message);
}
}
public class Account {
private long balance;
public Account() { }
public long getBalance() {
return balance;
}
public void deposit(int money) {
balance += money;
}
public void withdraw(int money) throws InsufficientException {
if(balance < money) {
throw new InsufficientException("잔고 부족: "+(money-balance)+" 모자람");
}
balance -= money;
}
}
public class AccountExample {
public static void main(String[] args) {
Account account = new Account();
//예금하기
account.deposit(10000);
System.out.println("예금액: " + account.getBalance());
//출금하기
try {
account.withdraw(30000);
} catch(InsufficientException e) {
String message = e.getMessage();
System.out.println(message);
}
}
}
이것이 자바다(신용권, 임경균 지음)