→ 예외를 처리하지 않으면 프로그램이 중단될 수 있음
의도하지 않은 예외 → 예외를 처리하지 않으면 이후 코드가 실행되지 않음
ex: 10 / 0 계산 → 산술예외(ArithmeticException) 발생

의도한 예외 : 특정 조건에서 의도적으로 예외 발생
→ throw 키워드를 통해 예외를 발생시킴
ex: 미성년자의 접근 막기

예외 구조와 종류

https://mangkyu.tistory.com/152
Error → 메모리가 부족하는 등과 같이 시스템이 비정상적인 상황에 발생
→ JVM에서 발생시키기에 대응 X
예외(Exception) : 애플리케이션 코드에서 예외가 발생했을 때
체크 예외(Checked Exception) : RuntimeException 클래스를 상속받지 않은 예외 클래스
복구 가능성이 있는 예외 → 예외를 처리하는 코드를 함께 작성(예외 처리하지 않으면 컴파일러 에러)
ex: SQLException, IOException
언체크 예외(UncheckedException) : RuntimeException을 상속받는 예외 클래스
런타임 예외 → 예상치 못했던 상황에서 발생하는 것이 아님
복구 가능성이 없는 예외 → 예외 처리를 강제하지 않음(예외 처리하지 않아도 컴파일 에러 X)
ex : NullPointerException, IllegalArgumentException
예외 전파 : 메서드에서 발생한 예외가 해당 메서드 안에서 처리되지 않았을 때, 해당 메서드를 호출한 상위 메서드로 예외 전달
try {
exceptionPractice.callUncheckedException(); // 예외 생성
} catch (RuntimeException e) { // RuntimeException이 발생했을 때 처리하고 싶은 내용
System.out.println("언체크 예외 처리");
} catch (Exception e) { // Exception이 발생했을 때 처리하고 싶은 내용
System.out.println("체크 예외 처리");
}
<aside> 💡
throws : 예외를 호출한 곳에서 처리하도록 강제하는 방식
체크 예외의 경우 예외를 처리하지 않으면 컴파일 에러가 발생하는데, throws를 통해 예외 처리의 책임을 전가함으로써 컴파일 에러를 피할 수 있음
public void callCheckedException() throws Exception { // throws로 Exception 예외를 상위로 전파
if (true) {
System.out.println("체크예외 발생");
throw new Exception();
}
}
</aside>
Optional 객체 : null을 안전하게 다루게 하는 객체
→ if문을 활용해 null을 직접 처리할 수는 있지만, null이 발생할 가능성을 미리 예측하고 처리하는 것은 현실적으로 어려움
<aside> 💡
null : 프로그래밍에서 값이 없음 또는 참조하지 않음을 나타내는 키워드
NullPointerException : Null을 반환할 때 생기는 언체크 예외 → 컴파일러가 잡아주지 못하기 때문에, 예외가 발생하면 프로그램이 종료됨
</aside>
Optional 객체 활용 방법
Optional.ofNullable()을 사용해 null이 반환될 수 있는 객체 감싸기
import java.util.Optional;
public class Student {
// 속성
private String name;
// 생성자
// 기능
public String getName() {
return this.name;
}
}
public class Camp {
private Student student;
// null 이 반환될 수 있음을 명확하게 표시
public Optional<Student> getStudent() { // 데이터 반환 타입을 맞춰야 함
return Optional.ofNullable(student); // 해당 코드가 실행될 시점에 student가 null이라면, Optional 객체가 null을 감싸서 반환하고,
// student 데이터가 있을 경우, 해당 데이터를 감싸서 반환함
}
public void setStudent(Student student) {
this.student = student;
}
}
public class Main {
public static void main(String[] args) {
Camp camp = new Camp();
// Optional 객체가 반환되면서 해당 객체가 null일 경우가 있음을 알려줄 수 있음
Optional<Student> studentOptional = camp.getStudent();
}
}
isPresent()와 같은 Optional API를 통해서 안전하게 null 처리
isPresent() : 내부의 값이 존재할 경우 true를 반환
public class Main {
public static void main(String[] args) {
Camp camp = new Camp();
Student newStudent = new Student();
camp.setStudent(newStudent);
// Optional 객체 반환받음
Optional<Student> studentOptional = camp.getStudent();
// Optional 객체의 기능 활용
boolean flag = studentOptional.isPresent();
if (flag) {
// 존재할 경우
Student student = studentOptional.get(); // 안전하게 Student 객체 가져오기
String studentName = student.getName();
System.out.println("studentName = " + studentName);
} else {
// null일 경우
System.out.println("학생이 없습니다.");
}
}
}
orElseGet() : 값이 없을 때만 기본값을 제공하는 로직을 실행
import java.util.Optional;
public class Main {
public static void main(String[] args) {
Camp camp = new Camp();
// Optional 객체의 기능 활용
Student student = camp.getStudent()
.orElseGet(() -> new Student("미등록 학생"));
System.out.println("studentName = " + student.getName());
}
}