자바에서는 try, catch, finally, throws, throw 키워드를 사용하여 예외를 처리합니다.
try {
// 예외가 발생할 수 있는 코드
} catch (ExceptionType1 e) {
// ExceptionType1 예외를 처리하는 코드
} catch (ExceptionType2 e) {
// ExceptionType2 예외를 처리하는 코드
}
try {
// 예외가 발생할 수 있는 코드
} catch (Exception e) {
// 예외 처리 코드
} finally {
// 항상 실행되는 코드
}
finally 블록은 try 또는 catch 블록의 실행 여부와 관계없이 항상 실행됩니다. 자원 해제(예: 파일 닫기)에 주로 사용됩니다.
if (someCondition) {
throw new Exception("Custom Error Message");
}
public void someMethod() throws IOException, NullPointerException {
// 예외가 발생할 수 있는 코드
}
;) 누락, 잘못된 변수 선언.
package com.tenco.exception;
import java.util.InputMismatchException;
import java.util.Scanner;
public class FinallyHandling {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
System.out.println("숫자를 입력하시오");
int result = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("사용자야 정수값만 넣어주길 바래!");
} catch (Exception e) {
System.out.println(e.getClass() + ", " + e.getMessage());
} finally {
// 반드시 수행되어야 할 코드 영역
// 심지어 return 키워드를 만나더라도 여기는 수행이 됩니다.
// 키보드를 통해 들어오는 값을 받는 자원 해제
scanner.close();
}
System.out.println("비정상 종료 되지 않았습니다");
} // end of main
}
배열을 벗어났을때 상황을 대비하여 예외처리를 하고 있다.
그리고 finally 로 무조건 실행하게 될 코드를 작성하여 스캐너를 닫아주고 있다.
입력에 사용한 자원을 정리하기 위해서이다.
throws를 사용하면 메서드 호출자가 예외를 처리하도록 책임을 위임합니다.
package com.tenco.exception;
public class ThrowsHandling {
public static void main(String[] args) {
Calc calc = new Calc();
try {
calc.divide(100, 0);
} catch (ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다");
}
} // end of main
} // end of class
class Calc {
public int divide(int n1, int n2) throws ArithmeticException {
System.out.println("정수 나눗셈 동작");
return n1 / n2; // 어떤 수를 0으로 나누면 ArithmeticException 발생 됨
}
}
package com.tenco.exception;
public class ThrowsHandling {
public static void main(String[] args) {
Calc calc = new Calc();
try {
calc.divide(100, 0);
} catch (ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다");
}
} // end of main
} // end of class
class Calc {
public int divide(int n1, int n2) throws ArithmeticException {
if (n2 == 0) {
System.out.println("0을 입력할 수 없습니다");
throw new ArithmeticException();
}
return n1 / n2; // 어떤 수를 0으로 나누면 ArithmeticException 발생 됨
}
}
이렇게 이코드에 해당하는 예외처리를 이걸 실행하는 호출자가 예외를 처리하게끔 던져버릴 수 있다.
사용자 정의 예외 클래스를 만들어 특정 상황에 맞는 예외를 처리할 수 있습니다. 이를 위해 Exception 또는 RuntimeException을 상속받습니다.
package com.tenco.exception;
// 사용자 정의 예외 클래스 만들기
public class DivideByZeroError extends RuntimeException {
// 자바개발자들이 미리 만들어 둔 예외 클래스는 default(기본) 메세지가 미리 만들어져 있다.
public DivideByZeroError(String message) {
super(message);
}
public static void main(String[] args) {
Calc2 calc2 = new Calc2();
try {
calc2.divide(10, 0);
} catch (ArithmeticException e) {
System.out.println("여기는 ArithmeticException 만 발생되면 호출 됨. ");
} catch (DivideByZeroError e2) {
System.out.println("어 내가 만든 예외 클래스가 발생 했네");
}
} // end of main
} // end of class
class Calc2 {
public int divide(int n1, int n2) {
System.out.println("사용자 정의 예외 클래스 사용해보기");
if(n2 == 0) {
throw new DivideByZeroError("0은 안됨.");
}
return n1 / n2;
}
}
n2가 0일때 내가 만들어둔 메서드 divideByzeroError이 발생한다.
package com.tenco.exception;
public class Password {
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() < 4) {
throw new PasswordException("비밀번호는 4글자 이상이어야 합니다");
}
this.password = password;
}
}
package com.tenco.exception;
public class SignUpMain {
public static void main(String[] args) {
// 테스트 코드
// String password; --> 대신 클래스의 이점을 활용
Password password = new Password();
// 원래는 setPassword 에 throws 가 걸려 있기 때문에 호출하는 입장에서 강제적으로
// try catch 구문을 작성할 수 있도록 툴이 알져 주게 된다.
try {
password.setPassword(null);
} catch (PasswordException e) {
System.err.println(e.getMessage());
} catch (Exception e2) {
System.err.println(e2.getClass() + ", " + e2.getMessage());
}
} // end of main
} // end of class
throws를 던져서 main에서 호출할때 main 메서드가 예외를 처리하는 모습이다.
그리고 예외는 checked exception과 unckecked exception이 있다.
첫번째는 컴파일러가 미리 검사하여 try catch문이나 throws를 써줘야 한다.
두번째는 throw만 쓰면 된다.