๋ชฉ์ฐจ
- ์๋ฐ Optional: 1. null์ ๋ฌด์์ธ๊ฐ?
- ์๋ฐ Optional: 2. Optional ์๊ฐ
- ์๋ฐ Optional: 3. Optional ์ค๊ฐ ์ฒ๋ฆฌ ๋ฉ์๋
- ์๋ฐ Optional: 4. Optional ์ข ๋จ ์ฒ๋ฆฌ ๋ฉ์๋
- ์๋ฐ Optional: 5. Optional ํบ์๋ณด๊ธฐ
null์ด ์ฃผ๋ ๋ฌธ์
์์ ๊ธ์์๋ ์๋ฐ ์ธ์ด์์ null์ ํน์ง๊ณผ ํจ๊ป ์๋ชป๋ null ์ฐธ์กฐ๋ก ์ธํด ๋ฐ์ํ๋ ๋ฌธ์ ๋ค์ ๋ํด์ ์์๋ณด์๋ค.
๋ด์ฉ์ ์ ๋ฆฌํด๋ณด๋ฉด, ๋ฐํ์์์ null์ ์๋ชป ์ฐธ์กฐํ๋ ๊ฒฝ์ฐ์๋ NullPointerException์ด ๋ฐ์ํ์ฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๊ณ
์ด๋ฅผ ํผํ๊ณ ์ ์๊ฒจ๋๋ ์ฒดํฌ ๋ก์ง์ผ๋ก ์ธํด ์ฝ๋๊ฐ ๋ณต์กํด์ง๋ ๋ฌธ์ ๊ฐ ์๋ค.
์ฌ์ค null ์ฒ๋ฆฌ๋ฅผ ๊ฐ์ ํ๋ ค๋ ๋
ธ๋ ฅ์ Optional ํด๋์ค ์ด์ ์๋ ์์๋ค. ์๋ฐ7 ์ โProject Coinโ์์๋
์์ ํธ์ถ(safe call)์ ์ํ ์๋น์ค ์ฐ์ฐ์(elvis operator)๊ฐ ์ ์๋์์ผ๋ ๊ฒฐ๊ณผ์ ์ผ๋ก๋ ์น์ธ๋์ง ์์๋ค.
์๋น์ค ์ฐ์ฐ์๋ ๋ณดํต ?:์ ๋งํ๋ค. ์๊ณ๋ฐฉํฅ์ผ๋ก 90๋ ํ์ ํ๋ฉด ์๋น์ค ํ๋ ์ฌ๋ฆฌ(Elvis Presley) ์ ๋ชจ์ต์ด ์ฐ์๋๋ค.
์๋ก์ด ์์ ์ฅ์น๋ฅผ ์ ์ฉํ๋ ์ด์ ์ด ๋์
ํ๋ ๋น์ฉ๋ณด๋ค ์ข์ง ์์๊ธฐ ๋๋ฌธ์ด๊ฒ ์ง๋ง, ์ ์์ด ์น์ธ๋์๋ค๋ฉด
์ฐ๋ฆฌ๋ ์๋ฐ์์ null์ด ์ฃผ๋ ๋ฌธ์ ๋ค์ ์๋์ ๊ฐ์ ์ฝ๋๋ก ํํผํ์์ง๋ ๋ชจ๋ฅธ๋ค.
// ํน์๋ ์ด๋ฐ ์ฝ๋๊ฐ ๊ฐ๋ฅํ์ง ์์์๊น?
public String getPhoneManufacturerName(Person person) {
// ์ฒด์ด๋ ์ค์์ null์ด ์๋ค๋ฉด, "Samsung"์ ๋ฐํํ๋ค.
return person?.getPhone()?.getManufacturer()?.getName() : "Samsung";
}
๊ทธ๋ ๋ค๋ฉด, ๋ณด๋ค ๋์ null ์ฒ๋ฆฌ๋ฅผ ์ํด ํ์ํ Optional ํด๋์ค๋ ๋ฌด์์ผ๊น?
Optional ํด๋์ค
java.util.Optional<T> ํด๋์ค๋ ํจ์ํ(Functional) ์ธ์ด์ธ ์ค์นผ๋ผ(Scala)์ ํ์ค์ผ(Haskell)์ ์ํฅ์ ๋ฐ์์ ํ์ํ๋ค.
์๋ง ์ค์นผ๋ผ์ Optional๊ณผ ํ์ค์ผ์ Maybe์ ์ํฅ์ด ์๋๊น ์ถ์ง๋ง, ์๋ฐ์ Optional์ ๋ชฉ์ ์ ๋ฐํ๋๋ ๊ฐ์ด โ์์โ์
๋ํ๋ด๋ ๊ฒ์ด๋ค. ์ด๋ ํด๋์ค์ ๋ฌ๋ฆฐ ์ฃผ์์ ํตํด์๋ ์ ์ ์๋๋ฐ, API Note ๋ถ๋ถ์ ์๋์ ๊ฐ์ด ๊ฐ๋ฐ์์ ์๋๊ฐ ๋ช
์๋ผ์๋ค.
Optional is primarily intended for use as a method return type where there is a clear need to represent โno result,โ and where using null is likely to cause errors. A variable whose type is Optional should never itself be null; it should always point to an Optional instance.
์ต์ ๋์ ์ฃผ๋ก โ๊ฒฐ๊ณผ ์์โ์ ๋ํ๋ผ ํ์๊ฐ ๋ถ๋ช ํ๊ณ
null์ ์ฌ์ฉํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ ๋ฉ์๋ ๋ฆฌํด ํ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ํ ๊ฒ์ด๋ค. ์ต์ ๋ ํ์ ์ ๋ณ์๋ ๊ทธ ์์ฒด๊ฐnull์ด๋ฉด ์ ๋๋ฉฐ ํญ์ Optional ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌ์ผ์ผ ํ๋ค.
Optional์ ๋น๋์ด ๋งํ๋ฉด ์ ๋ฆฌ๊ฐ์ด ํ์๋๊ธฐ ์ฌ์ด ๊ฒ์ ํฌ์ฅํ ๋ ๊ฐ์ธ๋ ์์ด์บก(์ผ๋ช
๋ฝ๋ฝ์ด)๊ณผ ๊ฐ๋ค. ์ฝ๊ฒ ๊นจ์ ธ๋ฒ๋ฆฌ๋
์ ๋ฆฌ์ฒ๋ผ, ์๋ชป ๋ค๋ฃจ๋ฉด ์ฌ๊ฐํ ์ค๋ฅ๋ฅผ ์ผ์ผํฌ ์ ์๋ null์ ์์ ํ๊ฒ ๋ค๋ฃฐ ์ ์๊ฒ ํด์ค๋ค.
๊ทธ๋ผ ์ด์ ๋ถํฐ Optional์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ํ๋์ฉ ์์๋ณด์.
Optional ๊ฐ์ฒด ์ ์ธ
Optional ํด๋์ค์ ๋ช
์ธ๋ฅผ ๋ณด๋ฉด ์ ์ ์๋ฏ์ด, ์ ๋ค๋ฆญ ํ์
์ผ๋ก ์ ๊ณต๋๋ค.
๋ฐ๋ผ์ ์ ์ธ๊ณผ ๋์์ ํ์
๋งค๊ฐ๋ณ์๋ฅผ ์ง์ ํ๋ค. ์ฆ, Optional์ด ๊ฐ์ธ๋ ๊ฐ์ฒด์ ํ์
์ ์ง์ ํ๋ค.
Optional<Person> person; // Person ํ์
์ `Optional` ๋ณ์
Optional<Phone> phone; // phone ํ์
์ `Optional` ๋ณ์
Optional ๊ฐ์ฒด ์์ฑ
Optional ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋(static factory method)๊ฐ ์ ๊ณต๋๋ค.
Optional.empty()
๋น์ด์๋ Optional ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ๋ด๋ถ์ ์ผ๋ก๋ Optional ํด๋์ค๊ฐ ๊ฐ์ง ์ฑ๊ธํด ์ธ์คํด์ค๋ฅผ ๋ฐํํ๊ฒ ๋๋ค.
โ๋น์ด์๋คโ ๋ผ๋ ์๋ฏธ์์ null๊ณผ ๋น์ทํ์ง๋ง, Optional.empty()๋ ์ฐธ์กฐํ๋๋ผ๋ NullPointerException๊ณผ ๊ฐ์ ์์ธ๊ฐ
๋ฐ์ํ์ง ์๋ ์ ์ด ๋ค๋ฅด๋ค.
// `Optional` ํด๋์ค์ ์ ์ ๋ฉค๋ฒ๋ก ์ ์ธ๋์ด ์์
private static final Optional<?> EMPTY = new Optional<>();
public static<T> Optional<T> empty() {
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
Optional.of(T value)
null์ด ์๋ ๊ฐ์ ๊ฐ์ธ๋ Optional ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ์ฌ๊ธฐ์ ๊ฐ์ด null์ธ ๊ฒฝ์ฐ NullPointerException์ด ๋ฐ์ํ๋ค.
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
Optional.ofNullable(T value)
null ๊ฐ์ ์ ์ฅํ ์ ์๋ Optional ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ๊ฐ์ด null์ธ ๊ฒฝ์ฐ ๋น Optional ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
๋ฐ๋ผ์ ์ธ์๋ก ๋๊ฒจ์ง๋ ๊ฐ์ด null์ผ์ง๋ ๋ชจ๋ฅด๋ ์ํฉ์์ ์ฌ์ฉํ๋ฉด ๋๋ค.
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
๊ฐ์ฒด๋ ์์ฑํ๋๋ฐ, ์ด๋ป๊ฒ ์ฌ์ฉํ์ง?
์ด๋ฒ๊ธ์์๋ Optional ํด๋์ค์ ๋ํ ์๊ฐ์ Optional ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด์๋ค.
์ด์ด์ง๋ ๊ธ์์๋ Optional ๊ฐ์ฒด์ ๊ฐ์ ํํฐ๋ง ํ๊ฑฐ๋ ๋ค๋ฅธ ํํ๋ก ๋ณํ์ํค๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์๊ฐํ๋ค.