Java8 null ๋Œ€์‹  Optional

null๋Œ€์‹  Optional์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž

๋‹ค์Œ ์ฒ˜๋Ÿผ ์‚ฌ๋žŒ์ด ์ž๋™์ฐจ๋ฅผ ๊ฐ–๊ณ , ์ž๋™์ฐจ๋Š” ์ž๋™์ฐจ ๋ณดํ—˜์„ ๊ฐ–๋Š” ๊ฐ์ฒด ๊ตฌ์กฐ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค๊ณ  ํ•˜์ž.

public class Person {
  private Car car;
  public Car getCar() {
    return car;
  }
}

public class Car {
  private Insurance insurance;
  public Insurance getInsurance() {
    return insurance;
  }
}

public class Insurance {
  private String name;
  public String getName() {
    return name;
  }

}

๋‹ค์Œ ์ฝ”๋“œ์—์„œ ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ• ๊นŒ?

public String getCarInsuranceName(Person person) {
        return person.getCar().getInsurance().getName();
    }
}

person ๊ฐ์ฒด๊ฐ€ null ์ด๋ฉด, getCar() ์ฐธ์กฐ๊ฐ€ null์ด๋ฉด NullpointerException์ด ๋ฐœ์ƒํ•œ๋‹ค.

๋ณด์ˆ˜์ ์ธ ์ž์„ธ๋กœ NullPointerException ์ค„์ด๊ธฐ

public String getCarInsuranceName2(Person person) {
  if (person != null) {
    Car car = person.getCar();
    if (car != null) {
      Insurance insurance = car.getInsurance();
      if (insurance != null) {
        return insurance.getName();
      }
    }
  }

  return "Unknown";
}

์ƒ์‹์ ์œผ๋กœ๋Š” ๋ชจ๋“  ํšŒ์‚ฌ์˜ ์ด๋ฆ„์ด ์žˆ์œผ๋ฏ€๋กœ ๋ณดํ—˜ํšŒ์‚ฌ์˜ ์ด๋ฆ„์ด null์ธ์ง€๋Š” ํ™•์ธํ•˜์ง€ ์•Š์•˜๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ํ™•์‹คํžˆ ์•Œ๊ณ  ์žˆ๋Š” ์˜์—ญ์„ ๋ชจ๋ธ๋ง ํ• ๋•Œ๋Š” ์ด๋Ÿฐ ์ง€์‹์„ ํ™œ์šฉํ•ด์„œ null ํ™•์ธ์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฐ” ํด๋ž˜์Šค๋กœ ๋ชจ๋ธ๋ง ํ• ๋•Œ๋Š” ์ด๊ฐ™์€ ์‚ฌ์‹ค์„ ๋‹จ์ •ํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

์œ„ ์ฝ”๋“œ๋Š” ๋ชจ๋“  ๋ณ€์ˆ˜๊ฐ€ null ์ธ์ง€ ์˜์‹ฌํ•˜๋ฏ€๋กœ ๋ณ€์ˆ˜๋ฅผ ์ ‘๊ทผํ•  ๋•Œ๋งˆ๋‹ค ์ค‘์ฒฉ๋œ if๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด์„œ ์ฝ”๋“œ ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€์ด ์ฆ๊ฐ€ํ•œ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ฐ˜๋ณต ํŒจํ„ด ์ฝ”๋“œ๋ฅผ ๊นŠ์€ ์˜์‹ฌ(deep doubt)๋ผ ํ•œ๋‹ค.

public String getCarInsuranceName2(Person person) {
  if (person != null) {
    Car car = person.getCar();
    if (car != null) {
      Insurance insurance = car.getInsurance();
      if (insurance != null) {
        return insurance.getName();
      }
    }
  }

  return "Unknown";
}

๋‹ค๋ฅธ ๋ฐฉ๋ฒ•2 : ๋„ˆ๋ฌด ๋งŽ์€ ์ถœ๊ตฌ

public String getCarInsuranceName3(Person person) {
  if (person == null) {
    return "Unknown";
  }

  final Car car = person.getCar();
  if (car == null) {
    return "Unknown";
  }

  final Insurance insurance = car.getInsurance();
  if (insurance == null) {
    return "Unknown";
  }

  return insurance.getName();
}


์œ„ ์ฝ”๋“œ๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ค‘์ฒฉ if๋ธ”๋ก์„ ์—†์•ด๋‹ค. ์ฆ‰, null ๋ณ€์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉด ์ฆ‰์‹œ โ€œUnknownโ€์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ด๊ฒƒ๋„ ์ข‹์€ ์ฝ”๋“œ๋Š” ์•„๋‹˜. ๋ฉ”์„œ๋“œ์— ๋„ค ๊ฐœ์˜ ์ถœ๊ตฌ๊ฐ€ ์ƒ๊ฒผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ถœ๊ตฌ ๋•Œ๋ฌธ์— ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ ์ง„๋‹ค. ๊ทธ๋ฆฌ๊ณ  Unknown ๋ฌธ์ž์—ด์ด ์„ธ๊ณณ์—์„œ ๋ฐ˜๋ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ์˜คํƒ€๋“ฑ์˜ ์‹ค์ˆ˜๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

null ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ

Optional์„ ์ด์šฉํ•œ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ ์žฌ์ •์˜

public class Person {
  private Optional<Car> car;
  public Optional<Car> getCar() {
    return car;
  }
}

public class Car {
  private Optional<Insurance> insurance;
  public Optional<Insurance> getInsurance() {
    return insurance;
  }
}

public class Insurance {
  private String name;
  public String getName() {
    return name;
  }
}

ํ•˜์Šค์ผˆ๊ณผ ์Šค์นผ๋ผ์˜ ์˜ํ–ฅ์„ ๋ฐ›์•„์„œ java.util.Optional ๋ผ๋Š” ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•จ. Optional์€ ์„ ํƒํ˜• ๊ฐ’์„ ์บก์Šํ™”ํ•˜๋Š” ํด๋ž˜์Šค๋‹ค. ๊ฐ’์ด ์žˆ์œผ๋ฉด Optional ํด๋ž˜์Šค๋Š” ๊ฐ’์„ ๊ฐ์‹ผ๋‹ค. ๋ฐ˜๋ฉด ๊ฐ’์ด ์—†์œผ๋ฉด Optional.empty ๋ฉ”์„œ๋“œ๋กœ Optional์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

Optional ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋ชจ๋ธ์˜ ์˜๋ฏธ semantic์ด ๋” ๋ช…ํ™•ํ•ด์กŒ๋‹ค. ์‚ฌ๋žŒ์€ Optional ๋ฅผ ์ฐธ์กฐํ•˜๋ฉฐ ์ž๋™์ฐจ๋Š” Optional๋ฅผ ์ฐธ์กฐํ•˜๋Š”๋ฐ ์ด๋Š” ์‚ฌ๋žŒ์ด ์ž๋™์ฐจ๋ฅผ ์†Œ์œ ํ–ˆ์„ ์ˆ˜๋„ ์•„๋‹ ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ, ์ž๋™์ฐจ๋Š” ๋ณดํ—˜์— ๊ฐ€์ž…๋˜์–ด ์žˆ์„ ์ˆ˜๋„ ์•„๋‹ ์ˆ˜๋„ ์žˆ์Œ์„ ๋ช…ํ™•ํžˆ ์„ค๋ช…ํ•œ๋‹ค.

๋˜ํ•œ ๋ณดํ—˜ํšŒ์‚ฌ ์ด๋ฆ„์€ Optional ์ด ์•„๋‹ˆ๋ผ Stringํ˜•์‹์œผ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๋Š”๋ฐ ์ด๋Š” ๋ณดํ—˜ํšŒ์‚ฌ๋Š” ๋ฐ˜๋“œ์‹œ ์ด๋ฆ„์„ ๊ฐ€์ ธ์•ผ ํ•จ์„ ๋ณด์—ฌ์ค€๋‹ค. ๋ณดํ—˜ํšŒ์‚ฌ ์ด๋ฆ„์„ ์ฐธ์กฐํ•  ๋•Œ NPE์ด ๋ฐœ์ƒํ• ์ˆ˜ ๋„ ์žˆ๋‹ค๋Š” ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ณดํ—˜ํšŒ์‚ฌ ์ด๋ฆ„์ด null์ธ์ง€ ์•„๋‹Œ์ง€ ํ™•์ธํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ํ•„์š”๋Š” ์—†๋‹ค. ์˜คํžˆ๋ ค ๊ณ ์ณ์•ผ ํ•  ๋ฌธ์ œ๋ฅผ ๊ฐ์ถ”๋Š” ๊ผด์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ณดํ—˜ํšŒ์‚ฌ๋Š” ๋ฐ˜๋“œ์‹œ ์ด๋ฆ„์„ ๊ฐ€์ ธ์•ผ ํ•˜๋ฉฐ ์ด๋ฆ„์ด ์—†๋Š” ๋ณดํ—˜ํšŒ์‚ฌ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ๋‹ค๋ฉด ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ณดํ—˜ํšŒ์‚ฌ ์ด๋ฆ„์ด ์—†๋Š” ์ด์œ ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๋ฐํ˜€์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

๋ชจ๋“  null์ฐธ์กฐ๋ฅผ Optional๋กœ ๋Œ€์น˜ํ•˜๋Š” ๊ฒƒ์€ ๋ฐ”๋žŒ์งํ•˜์ง€ ์•Š๋‹ค. Optional์˜ ์—ญํ• ์€ ๋” ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด API๋ฅผ ์„ค๊ณ„ํ•˜๋„๋ก ๋•๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋งŒ ๋ณด๊ณ ๋„ ์„ ํƒํ˜• ๊ฐ’์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

optional๋กœ ์ž๋™์ฐจ ๋ณดํ—˜ํšŒ์‚ฌ ์ด๋ฆ„ ์ฐพ๊ธฐ

public String getCarInsuranceName(Optional<Person> person) {
  return person.flatMap(Person::getCar)
    .flatMap(Car::getInsurance)
    .map(Insurance::getName)
    .orElse("Unknown");
}

Optional ์ค‘์ฒฉ์— ๋”ฐ๋ฅธ ํ‰์ค€ํ™” ? flatMap ? ํ‰์ค€ํ™” ๊ณผ์ •์ด๋ž€ ์ด๋ก ์ ์œผ๋กœ ๋‘ Optional์„ ํ•ฉ์น˜๋Š” ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ ๋‘˜์ค‘ ํ•˜๋‚˜๋ผ๋„ null์ด๋ฉด ๋นˆ Optional์„ ์ƒ์„ฑํ•˜๋Š” ์—ฐ์‚ฐ์ด๋‹ค. flatMap์„ ๋นˆ Optional์— ํ˜ธ์ถœํ•˜๋ฉด ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๊ณ  ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.

๋„๋ฉ”์ธ ๋ชจ๋ธ์— Optional์„ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง๋ ฌํ™” ํ•  ์ˆ˜ ์—†๋Š” ์ด์œ 

์ž๋ฐ” ์–ธ์–ด ์•„ํ‚คํ…ํŠธ์ธ ๋ธŒ๋ผ์ด์–ธ ๊ณ ์ธ ๋Š” Optional์˜ ์šฉ๋„๊ฐ€ ์„ ํƒํ˜• ๋ฐ˜ํ™˜๊ฐ’์„ ์ง€์›ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ์ด์•ผ๊ธฐํ–ˆ๋‹ค.

Optional ํด๋ž˜์Šค๋Š” ํ•„๋“œ ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ฐ€์ •ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ Serializable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ ๋„๋ฉ”์ธ ๋ชจ๋ธ์— Optional์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ง๋ ฌํ™” ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๋„๊ตฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋‹จ์ ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์—ฌ์ „ํžˆ Optional์„ ์‚ฌ์šฉํ•ด์„œ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์ง๋ ฌํ™” ๋ชจ๋ธ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ๋‹ค์Œ ์˜ˆ์ œ์—์„œ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Optional๋กœ ๊ฐ’์„ ๋ฐ˜ํ™˜ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์„ ๊ถŒ์žฅํ•œ๋‹ค.

public class Person {
  private Car car;
  private Optional<Car> getCarAsOptional(){
    return Optional.ofNullable(car);
  }
}

๋””ํดํŠธ ์•ก์…˜๊ณผ Optional ์–ธ๋žฉ

Optional ์„ ์‚ฌ์šฉํ•œ ์‹ค์šฉ์˜ˆ์ œ

์ž ์žฌ์ ์œผ๋กœ null์ด ๋  ์ˆ˜ ์žˆ๋Š” ๋Œ€์ƒ์„ Optional๋กœ ๊ฐ์‚ฌ๊ธฐ

Object value = map.get("key");

Optional<Object> value = Optional.ofNullable(map.get("key"));

์˜ˆ์™ธ์™€ Optionalํด๋ž˜์Šค

์ž๋ฐ” API๋Š” ์–ด๋–ค ์ด์œ ์—์„œ ๊ฐ’์„ ์ œ๊ณตํ•  ์ˆ˜ ์—†์„ ๋•Œ null์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋Œ€์‹  ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ๋•Œ๋„ ์žˆ๋‹ค. ์ „ํ˜•์ ์ธ ์˜ˆ๊ฐ€ ๋ฌธ์ž์—ด์„ ์ •์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜๋Š” Integer.parseInt(String) ๋ฉ”์„œ๋“œ๋‹ค. ๋ฌธ์ž์—ด์„ ์ •์ˆ˜๋กœ ๋ฐ”๊พธ์ง€ ๋ชปํ•  ๋•Œ NUmberFormatException์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. ์ด๊ฒƒ์„Optional๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. (์ž‘์€ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ)

public static Optional<Integer> stringToInt(String s){
  try {
    return Optional.of(Integer.parseInt(s));
  } catch (NumberFormatException e){
    return Optional.empty();
  }
}

๊ธฐ๋ณธํ˜• Optional์„ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•˜๋Š”์ด์œ 

์ŠคํŠธ๋ฆผ์ฒ˜๋Ÿผ Optional๋„ ๊ธฐ๋ณธํ˜•์œผ๋กœ ํŠนํ™”๋œ OptionalInt, OptionalLong, OptionalDouble๋“ฑ์˜ ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ŠคํŠธ๋ฆผ์ด ๋งŽ์€ ์š”์†Œ๋ฅผ ๊ฐ€์งˆ๋•Œ๋Š” ๊ธฐ๋ณธํ˜• ํŠนํ™” ์ŠคํŠธ๋ฆผ์„ ์ด์šฉํ•ด์„œ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ–ˆ๋‹ค.(๋ฐ•์‹ฑ) ํ•˜์ง€๋งŒ Optional์˜ ์ตœ๋Œ€์š”์†Œ์ˆ˜๋Š” ํ•œ๊ฐœ ์ด๋ฏ€๋กœ Optional์—์„œ๋Š” ๊ธฐ๋ณธํ˜• ํŠนํ™” ํด๋ž˜์Šค๋กœ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์—†๋‹ค. ๋˜ํ•œ ๊ธฐ๋ณธํ˜• ํŠนํ™” Optional๋กœ ์ƒ์„ฑํ•œ ๊ฒฐ๊ณผ๋Š” ๋‹ค๋ฅธ ์ผ๋ฐ˜ Optional๊ณผ ํ˜ผ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

์‘์šฉ

์˜ˆ๋ฅผ ๋“ค์–ด ํ”„๋กœ๊ทธ๋žจ ์„ค์ • ์ธ์ˆ˜๋กœ Properties๋ฅผ ์ „๋‹ฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.

Properties properties = new Properties();
properties.setProperty("a", "5");
properties.setProperty("b", "true");
properties.setProperty("c", "-3");

์ด์ œ ํ”„๋กœ๊ทธ๋žจ์—์„œ Properties๋ฅผ ์ฝ์–ด์„œ ๊ฐ’์„ ์ดˆ ๋‹จ์œ„๋กœ ์ง€์†์‹œ๊ฐ„์œผ๋กœ ํ•ด์„ํ•œ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์„œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋กœ ์ง€์†์‹œ๊ฐ„์„ ์ฝ์„ ๊ฒƒ์ด๋‹ค.

public int readDuration(Properties props, String name)

์ง€์†์‹œ๊ฐ„์€ ์–‘์ˆ˜์—ฌ์•ผ ํ•˜๋ฏ€๋กœ ๋ฌธ์ž์—ด์ด ์–‘์˜ ์ •์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉด ํ•ด๋‹น ์ •์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ ๊ทธ ์™ธ์—๋Š” 0์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด๋ฅผ ๋‹ค์Œ ์ฒ˜๋ŸผJunit ์–ด์„ค์…˜์œผ๋กœ ๊ตฌํ˜„ํ• ์ˆ˜ ์žˆ๋‹ค.

assertEquals(5, readDuration(param, "a"));
assertEquals(0, readDuration(param, "b"));
assertEquals(0, readDuration(param, "c"));
assertEquals(0, readDuration(param, "d"));
public int readDuration(Properties props, String name){
  String value = props.getProperty(name);
  if(value != null){
    try{
     int i = Integer.parseInt(value) ;
      if (i > 0){
        return u;
      }
    }catch (NumberFormatException e){}
  }
  return 0;
}

์ด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฐœ์„ ํ• ๊นŒ?

public int readDuration(Properties props, String name){
  return Optional.ofNullable(props.getProperty(name))
    .flatMap(OptionalUtility::stringToInt)
    .filter(i-> i>0)
    .orElse(0);
}

Properties์˜ ๊ฐ’์ด null ๊ฐ’์ผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ofNullable ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ Optional๋กœ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ”๊พธ๊ณ , ์•ž์—์„œ ๋งŒ๋“  Integer.parseInt(String) ์„ Optional ๋กœ ์ฒ˜๋ฆฌํ•œ ๊ฒƒ์ฒ˜๋Ÿผ OptionalUtilty.stringToInt ๋ฉ”์„œ๋“œ ์ฐธ์กฐ๋ฅผ ์ „๋‹ฌํ•ด์„œ Optional์—์„œ Optional๋กœ ๋ฐ”๊พผ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ์Œ์ˆ˜๋ฅผ ํ•„ํ„ฐ๋งํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ 0์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์—ฐ๊ด€ ํฌ์ŠคํŠธ