1) ์ต์ ๋ (Optional)
(1) ๊ฐ์
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.
- ์์ ๋ด์ฉ์ JDK 8 API Document์ ์ฃผ์์ผ๋ก ์ ํ์๋ ๋ถ๋ถ ์ค ์ผ๋ถ๋ฅผ ๋ฐ์ทํ ๊ฒ์ผ๋ก, ์์ญํ์๋ฉด Java Optional ํด๋์ค๋ Java 8์์ ์ถ๊ฐ๋ ํด๋์ค๋ก Java์ ๊ณ ์ง์ ์ธ ๋ฌธ์ ์ธ NPE (NullPointer Exception) ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค.
- ์ฆ, Optional ํด๋์ค๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ํ๋ก๊ทธ๋จ ์คํ ์ค Null ๊ฐ์ผ๋ก ์ธํด ๋ฐ์ํ ์ ์๋ ๋ฐํ์ ์๋ฌ๋ฅผ ํจ์จ์ ์ผ๋ก ๋ฐฉ์งํ ์ ์๋ ๊ฒ์ด๋ค!
(2) Optional ํด๋์ค
- Optional ํด๋์ค๋ Integer๋ Double ํด๋์ค์ฒ๋ผ “T” ํ์ ์ ๊ฐ์ฒด๋ฅผ ํฌ์ฅํด์ฃผ๋ ๋ํผ ํด๋์ค (Wrapper Class)๋ก, Optional ์ธ์คํด์ค๋ ๋ชจ๋ ํ์ ์ ์ฐธ์กฐ ๋ณ์๋ฅผ ์ ์ฅํ ์ ์๋ค.
- ๊ธฐ์กด์๋ NPE ์์ธ๋ฅผ ๋ณต์กํ ์กฐ๊ฑด๋ฌธ์ ํตํด ์ฒ๋ฆฌํ์ง๋ง Optional ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๊ณต๋๋ ๋ฉ์๋๋ฅผ ํตํด ๊ฐ๋จํ ํํผํ ์ ์๋ค.
- ๊ทธ๋ผ ์ด์ ์ฝ๋๋ฅผ ํตํด Optional ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉํ๋ฉด์ ์ดํดํด๋ณด์!
(3) Optional ๊ฐ์ฒด ์์ฑ
- Optional ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฉ์๋๋ ํฌ๊ฒ of(), ofNullable(), empty() ๋ฉ์๋๊ฐ ์๋ค.
โ Optional.of()
- null์ด ์๋ ๋ช ์๋ ๊ฐ์ ๊ฐ์ง๋ Optional ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
Optional<String> hello = Optional.of("Hello World!!");
→ OK!
Optional<Object> nullTest = Optional.of(null);
→ NPE ์์ธ ๋ฐ์!!
- of() ๋ฉ์๋ ์์ ํ๋ผ๋ฏธํฐ๋ก null ๊ฐ์ ์ฃผ๊ฒ ๋๋ฉด NPE ์์ธ๊ฐ ๋ฐ์ํ๋ค.
- ์ฆ, null ๊ฐ์ ํ์ฉํ์ง ์์ผ๋ฏ๋ก ํ๋ผ๋ฏธํฐ๋ก null ๊ฐ์ด ์ฌ ์ ์๋ ๊ฒฝ์ฐ์๋ ์๋์ ofNullable() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
โก Optional.ofNullable()
- ๋ช ์๋ ๊ฐ์ด null์ด ์๋๋ฉด ๋ช ์๋ ๊ฐ์ ๊ฐ์ง๋ Optional ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฉฐ, ๋ช ์๋ ๊ฐ์ด null ์ด๋ฉด ๋น์ด์๋ Optional ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
Optional<String> hello = Optional.ofNullable("Hello World!!");
Optional<Object> nullTest = Optional.ofNullable(null);
โข Optional.empty()
- ์๋ฌด๋ฐ ๊ฐ๋ ๊ฐ์ง์ง ์๋ ๋น์ด์๋ Optional ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฉฐ, of() ๋ฉ์๋์ ๋ค๋ฅธ ์ ์ ์ฐธ์กฐํ๋๋ผ๋ NPE ์์ธ๊ฐ ๋ฐ์ํ์ง ์๋๋ค๋ ๊ฒ์ด๋ค.
Optional<Object> emptyTest = Optional.empty();
→ Optional.ofNullable(null) == Optional.empty()
(4) Optional ๊ฐ์ฒด ์ฌ์ฉ
โ get()
- Optional ๊ฐ์ฒด์ ์ ์ฅ๋ ๊ฐ์ ๋ฐํํ๋ค.
Optional<String> hello = Optional.ofNullable("Hello World!!");
String s = hello.get();
→ ์ฐธ์กฐ๋ณ์ s ์๋ "Hello World!!" ๊ฐ ์ ์ฅ๋๋ค.
Optional<Object> nullTest = Optional.ofNullable(null);
Object o = nullTest.get();
→ NoSuchElement Exception ๋ฐ์
- get() ๋ฉ์๋๋ฅผ ํตํด Optional ๊ฐ์ฒด์ ์ ์ฅ๋ ๊ฐ์ ๊ฐ์ ธ์ค๊ณ ์ ํ ๋, ๊ฐ์ด null ์ด๋ฉด NoSuchElementException ์์ธ๊ฐ ๋ฐ์ํ๋ฏ๋ก ์ด๋ฌํ ๊ฒฝ์ฐ์๋ ์๋์ orElse() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๋์ฒดํ ๊ฐ์ ์ง์ ํ ์ ์๋ค.
- ๊ทธ๋ฆฌ๊ณ orElse() ๋ฉ์๋์ ๋ณํ์ผ๋ก null์ ๋์ฒดํ ๊ฐ์ ๋ฐํํ๋ ๋๋ค์์ ์ง์ ํ ์ ์๋ orElseGet() ๋ฉ์๋์ null์ผ ๋, ์ง์ ๋ ์์ธ๋ฅผ ๋ฐ์์ํค๋ orElseThrow() ๋ฉ์๋๊ฐ ์๋ค.
โก orElse()
- Optional ๊ฐ์ฒด์ ์ ์ฅ๋ ๊ฐ์ ๋ฐํํ์ง๋ง null์ด ์ ์ฅ๋ ๊ฒฝ์ฐ์๋ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ ๊ฐ์ ๋ฐํํ๋ค.
[์ฝ๋]
Optional<String> hello = Optional.ofNullable("Hello World!!");
String s = hello.orElse("๊ธฐ๋ณธ๊ฐ");
System.out.println(s);
Optional<Object> nullTest = Optional.ofNullable(null);
Object o = nullTest.orElse("๊ธฐ๋ณธ๊ฐ");
System.out.println(o);
[๊ฒฐ๊ณผ]
Hello World!!
๊ธฐ๋ณธ๊ฐ
- ์ถ๊ฐ์ ์ผ๋ก orElse() ๋ฉ์๋๋ ์ฌ์ฉํ ๋, ์ฃผ์ํ ์ ์ด ์๋๋ฐ ์๋์ ์ฝ๋๋ฅผ ๋ณด๋๋ก ํ์!
[์ฝ๋]
class OrElse {
public static int sequence = 0;
OrElse() {
++sequence;
System.out.println(sequence + "๋ฒ์จฐ OrElse ๊ฐ์ฒด ์์ฑ!!!");
}
}
public class Test {
public static void main(String[] args) {
OrElse orElse = new OrElse();
Optional<OrElse> first = Optional.ofNullable(orElse);
OrElse test = first.orElse(new OrElse());
}
}
[๊ฒฐ๊ณผ]
1๋ฒ์จฐ OrElse ๊ฐ์ฒด ์์ฑ!!!
2๋ฒ์จฐ OrElse ๊ฐ์ฒด ์์ฑ!!!
- orElse() ๋ฉ์๋๋ ์ ์ฝ๋ ๊ฒฐ๊ณผ์ฒ๋ผ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ด์ฉ์ ๊ฐ์ด ์๋ ์๋ ๋ฌด์กฐ๊ฑด ์คํ๋๋ค.
- ๋ฐ๋ผ์, orElse() ๋ฉ์๋ ๋ณด๋ค๋ ์๋์ orElseGet() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋๋ก ํ์!
โข orElseGet()
- Optional ๊ฐ์ฒด์ ์ ์ฅ๋ ๊ฐ์ ๋ฐํํ์ง๋ง null์ด ์ ์ฅ๋ ๊ฒฝ์ฐ์๋ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ ๋๋ค์์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ๋ค.
[์ฝ๋]
class OrElse {
public static int sequence = 0;
OrElse() {
++sequence;
System.out.println(sequence + "๋ฒ์จฐ OrElse ๊ฐ์ฒด ์์ฑ!!!");
}
}
public class Test {
public static void main(String[] args) {
OrElse orElse = new OrElse();
Optional<OrElse> first = Optional.ofNullable(orElse);
OrElse test = first.orElseGet(() -> {
return new OrElse();
});
}
}
[๊ฒฐ๊ณผ]
1๋ฒ์จฐ OrElse ๊ฐ์ฒด ์์ฑ!!!
โฃ orElseThrow()
- Optional ๊ฐ์ฒด์ ์ ์ฅ๋ ๊ฐ์ ๋ฐํํ์ง๋ง null์ด ์ ์ฅ๋ ๊ฒฝ์ฐ์๋ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค.
Optional<String> hello = Optional.ofNullable(null);
String s = hello.orElseThrow(() -> {
throw new IllegalArgumentException();
});
โค isPresent()
- Optional ๊ฐ์ฒด์ ์ ์ฅ๋ ๊ฐ์ด ์กด์ฌํ๋ฉด true๋ฅผ ๋ฐํํ๊ณ , null์ด ์ ์ฅ๋ ๊ฒฝ์ฐ์๋ false๋ฅผ ๋ฐํํ๋ค.
[์ฝ๋]
Optional<String> True = Optional.ofNullable("hello");
Optional<String> False = Optional.ofNullable(null);
System.out.println(True.isPresent());
System.out.println(False.isPresent());
[๊ฒฐ๊ณผ]
true
false
โฅ ifPresent()
- Optional ๊ฐ์ฒด์ ์ ์ฅ๋ ๊ฐ์ด ์กด์ฌํ๋ฉด ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ฐ์ ๋๋ค์์ ์คํํ๋ฉฐ, null์ด ์ ์ฅ๋ ๊ฒฝ์ฐ์๋ ์คํํ์ง ์๋๋ค.
Optional<String> True = Optional.ofNullable("hello");
Optional<String> False = Optional.ofNullable(null);
True.ifPresent((data) -> {
System.out.println("๊ฐ์ด ์กด์ฌํจ : " + data);
});
False.ifPresent((data) -> {
System.out.println("๊ฐ์ด ์์ด์ ํด๋น ๋ก์ง์ ์คํ๋์ง ์์");
});
→ Optional์ ์ฌ์ฉํ์ง ์๊ณ null ๊ฐ์ ์ฒดํฌํ์ฌ ํน์ ๋ก์ง์ ์คํํ๋๋ก ์ฝ๋๋ฅผ ์ง๋ณด์!
String s = "hi";
if (s != null) {
System.out.println("๊ฐ์ด ์กด์ฌํจ : " + s);
}
→ Optional์ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ ์ฝ๋์ฒ๋ผ null ๊ฐ์ ์ฒดํฌํ๋ if๋ฌธ์ ์จ์ฃผ๊ณ ์ฝ๋๊ฐ ๊ธธ์ด์ง๊ธฐ ๋๋ฌธ์ ์ ๋งํ๋ฉด Optional์ ์ฌ์ฉํด์ ์ฝ๊ณ ํธ๋ฆฌํ๊ฒ ์ฝ๋ฉํ์!
(5) ๊ธฐ๋ณธ ํ์ ์ Optional ํด๋์ค
- Java์์๋ ๊ธฐ๋ณธ ํ์ ์ ์ํ ๋ณ๋์ Optional ํด๋์ค๋ฅผ ์ ๊ณตํ๋ค.
- ๋ง์ฝ, Optional ๊ฐ์ฒด์ ์ ์ฅ๋๋ ๊ฐ์ด int, long, double ์ด๋ผ๋ฉด Auto Boxing / UnBoxing์ด ๋ฐ์ํ๋ Optional<\Integer>, Optional<\Long>, Optional<\Double>์ ์ฌ์ฉํ์ง ์๊ณ OptionalInt, OptionalLong, OptionalDouble์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
- ์ด์ฒ๋ผ ๊ธฐ๋ณธ ํ์ ์ ์ํ Optional ํด๋์ค๋ ๋ฐํ ํ์ ์ด Optional<\T> ํ์ ์ด ์๋๋ผ ํด๋น ๊ธฐ๋ณธ ํ์ ์ด๋ผ๋ ์ฌ์ค๋ง ์ ์ธํ๋ฉด ๊ฑฐ์ ๋ชจ๋ ๋ฉด์์ ๋น์ทํ๋ค.
- ๋ฐ๋ผ์, Optional ๊ฐ์ฒด์์ get() ๋ฑ์ ์ฌ์ฉํ์ฌ ์ ์ฅ๋ ๊ฐ์ ์ ๊ทผํ ์ ์๋ ๊ฒ์ฒ๋ผ ํด๋์ค ๋ณ๋ก ์ ์ฅ๋ ๊ฐ์ ์ ๊ทผํ ์ ์๋ ๋ค์๊ณผ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋๋ฐ ์ฝ๋๋ฅผ ํตํด ์์๋ณด๋๋ก ํ์!
โ OptionalInt ํด๋์ค
OptionalInt optionalInt = OptionalInt.of(100);
int number = optionalInt.getAsInt();
System.out.println(number);
โก OptionalLong ํด๋์ค
OptionalLong optionalLong = OptionalLong.of(100L);
long number = optionalLong.getAsLong();
System.out.println(number);
โข OptionalDouble ํด๋์ค
OptionalDouble optionalDouble = OptionalDouble.of(3.14);
double number = optionalDouble.getAsDouble();
System.out.println(number);
(6) Optional ์ฌ์ฉ ์, ์ฃผ์ ์ฌํญ
โ isPresent() + get() ๋ฉ์๋ ๋์ orElseGet()์ ์ฌ์ฉํ๋ค!
- ์ฝ๋๋ฅผ ์ค์ผ ์ ์๋ค!
โก orElse() ๋์ orElseGet()์ ์ฌ์ฉํ๋ค!
- orElse()๋ Optional ๊ฐ์ฒด์ ์ ์ฅ๋ ๊ฐ์ด ์๋ ์๋ ์ธ์๋ก ์ ๋ฌ๋ ๋ด์ฉ์ ๋ฌด์กฐ๊ฑด ์คํํ๊ธฐ ๋๋ฌธ์ด๋ค.
โข of(), ofNullable() ํผ๋ํ์ง ๋ง์!
โฃ ๊ธฐ๋ณธ ํ์ ์ด๋ผ๋ฉด Optional<\T> ๋์ OptionalInt, Long, Double ์ฌ์ฉํ์!
โค Optional ๊ฐ์ฒด๋ฅผ ์ปฌ๋ ์ ์ ์์๋ก ์ฌ์ฉํ์ง ๋ง์!
[Reference]
- https://ittrue.tistory.com/166?category=958774
- http://www.tcpschool.com/java/java_stream_optional
- https://wildeveloperetrain.tistory.com/91
- https://jdm.kr/blog/234
- https://docs.oracle.com/javase/8/docs/api/
- https://bibi6666667.tistory.com/286
๋ฐ์ํ
'๐ง Programming > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
IntelliJ ์ธ์ฝ๋ฉ ์ค์ (0) | 2023.08.18 |
---|---|
์ ๋ค๋ฆญ (5) - ๊ณต๋ณ์ฑ, ๋ฐ๊ณต๋ณ์ฑ, ๋ฌด๊ณต๋ณ์ฑ (0) | 2023.07.25 |
์ ๋ค๋ฆญ (4) - ์ ํ๋ ํ์ ํ๋ผ๋ฏธํฐ (0) | 2023.07.23 |
์ ๋ค๋ฆญ (3) - ์ ๋ค๋ฆญ ํด๋์ค์ ์ ๋ค๋ฆญ ๋ฉ์๋ (0) | 2023.07.22 |
์ ๋ค๋ฆญ (2) - ์ ๋ค๋ฆญ & ํ์ ํ๋ผ๋ฏธํฐ (0) | 2023.07.22 |