📙 목차
🧡 학습 목표
- Optional 을 사용하는 이유와 개념을 학습한다.
1. Optional 이란?
- null 을 안전하게 다루게 해주는 객체
- null 을 직접 다루는 대신 Optional 을 사용하면 NullPointerException 을 방지할 수 있다.
- NPE(NullPointerException) 예외는 런타임 예외이고 컴파일러가 잡아주지 못 한다.
💡 null 이란?
프로그래밍에서 값이 없음 또는 참조하지 않음 을 나타내는 키워드
예시 - Optional이 필요한 상황
public class Student {
private String name;
public String getName() {
return this.name;
}
}
-----
public class Camp {
private Student student;
// ⚠️ null 을 반환할 수 있는 메서드
public Student getStudent() {
return student;
}
}
-----
public class Main {
public static void main(String[] args) {
Camp camp = new Camp();
Student student = camp.getStudent(); // ⚠️ student 에는 null 이 담김
String studentName = student.getName(); // 🔥 NPE 발생 -> 프로그램 종료
System.out.println("studentName = " + studentName);
}
}
* NULL 을 직접 처리의 한계
- if 문을 활용해서 null 처리를 할 수 있지만, 모든 코드에서 null 이 발생할 가능성을 미리 예측하고 처리하는 것은 현실적으로 어렵다.
public class Main {
public static void main(String[] args) {
Camp camp = new Camp();
Student student = camp.getStudent();
String studentName;
if (student != null) { // ⚠️ 가능은하지만 현실적으로 어려움
studentName = student.getName();
} else {
studentName = "등록된 학생 없음"; // 기본값 제공
}
System.out.println("studentName = " + studentName);
}
}
2. Optional 활용하기
<참고 자료>
Optional (Java Platform SE 8 )
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value. Additional methods that depend on the presence or absence of a contained value are provided, such as orEl
docs.oracle.com
- Optional 객체는 값이 있을 수도 있고 없을 수도 있는 컨테이너라고 생각한다.
- Optional 객체를 메서드 반환 자료형에 선언해서 해당 메서드가 null 이 반환될 가능성을 명확하게 전달할 수 있다.
- Optional.ofNullable() 을 사용하여 null 이 반환될 수 있는 객체를 감싼다.
- 활용할 때는 isPresent() 와 같은 Optional API 를 통해 안전하게 null 처리를 할 수 있다.
isPresent()
- Optional 내부의 값이 존재할 경우에 true 반환
- 내부 값이 null 일 경우 false 를 반환
import java.util.Optional;
public class Camp {
private Student student;
// ✅ null 이 반환될 수 있음을 명확하게 표시
public Optional<Student> getStudent() {
return Optional.ofNullable(student);
}
}
-----
public class Main {
public static void main(String[] args) {
Camp camp = new Camp();
// 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 {
System.out.println("학생이 없습니다.");
}
}
}
orElseGet()
- orElseGet()은 값이 없을 때만 기본값을 제공하는 로직을 실행하는 메서드이다.
- 값이 있을때는 기존 값을 그대로 get 한다.
- orElseGet()을 제대로 활용하려면 람다 표현식을 이해해야 한다.
import java.util.Optional;
public class Camp {
private Student student;
// ✅ null 이 반환될 수 있음을 명확하게 표시
public Optional<Student> getStudent() {
return Optional.ofNullable(student);
}
}
-----
public class Main {
public static void main(String[] args) {
Camp camp = new Camp();
// ✅ Optional 객체의 기능 활용 (orElseGet 사용)
Student student = camp.getStudent()
.orElseGet(() -> new Student("미등록 학생"));
System.out.println("studentName = " + student.getName());
}
}
3. 실습 과제
수강생의 이름을 입력받고 해당 이름이 캠프에 등록되어 있는지 확인하는 프로그램을 만드세요.
- Student , CampService , Main 클래스를 활용하세요.
- 캠프에는 3 명의 학생이 존재합니다. Spartan, Steve, John
- Optional.ofNullable() 로 Optional 객체를 만드세요
- isPresent() 로 Optional 에 값이 있는지 확인하세요.
- get() 으로 안전하게 데이터를 꺼내오세요.
public class Student {
private String name;
private String exp;
public Student(String name, String exp) {
this.name = name;
this.exp = exp;
}
public String getName(){
return name;
}
public void introduce(){
System.out.printf("안녕하세요. %s %s 입니다.\n", exp, this.name);
}
}
import java.util.Optional;
public class CampService {
static Student[] students = {
new Student("Spartan", "재학생"),
new Student("Steve", "재학생"),
new Student("John", "재학생")
};
public Optional<Student> searchStudent(String name) {
for (Student s : students) {
if (name.equals(s.getName())) {
return Optional.of(s);
}
}
return Optional.empty();
}
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("이름을 입력하시오: ");
String name = in.next();
CampService cs = new CampService();
cs.searchStudent(name).orElseGet(() -> {
System.out.println("등록되지 않은 학생, 등록 절차 진행 ...");
return new Student(name, "신입생");
}).introduce();
}
}
orElse
위 Main 클래스 코드의, orElseGet 과 동일하게 동작한다. (콘솔 출력 제외)
- 하지만, 이 코드는 Optional에 값이 있어도 불필요하게 객체를 생성하는 단점이 있다.
- 값이 자주 비어있고, 기본값 생성이 가벼운 경우 orElse 를 활용한다.
- 값이 자주 있고, 기본값 생성이 무겁거나 복잡한 경우 orElseGet 을 활용한다.
* orElseGet 내부 람다식은 Optional에 값이 없을 때만 실행된다.
cs.searchStudent(name).orElse(new Student(name, "신입생")).introduce();
Optional.of(value), Optional.ofNullable(value), Optional.empty() 차이
- Optional.of(value): 값이 확실히 있을 때 활용
- Optional.ofNullable(value): 값이 null일 수도 있을 때 활용, null일 경우 빈 Optional 이 된다.
- Optional.empty: 빈 Optional 을 만들고 싶을 때 활용
'Java > 강의' 카테고리의 다른 글
[📙 Java 문법 종합반] 3-4. 제네릭(Generic) (0) | 2025.04.16 |
---|---|
[📙 Java 문법 종합반] 3-3. 컬렉션(Collection) (1) | 2025.04.16 |
[📙 Java 문법 종합반] 3-1. 예외(Exception)과 예외처리(try-catch) (0) | 2025.04.16 |
[📙 Java 문법 종합반] 2-10. 객체지향 PART 4 - 다형성 (0) | 2025.04.15 |
[📙 Java 문법 종합반] 2-9. 객체지향 PART 3 - 추상화 (1) | 2025.04.15 |