JDK 1.8에서 Optional<T>이라는 클래스가 추가가 되었다. null에 대응하기 위해.

예제를 위한 아래의 두 클래스가 있다.

@Data
class Person {
    private String name;
    private int age;
}

@Data
class House {
    private Person owner;
    private String address;
}

 

이때, 콘솔에 집 정보를 출력하기 위해 다음과 같은 코드를 구현했다.

public class Main {

    public static void main(String[] args) {
        
        House house = houseService.getRandomHouse();
        System.out.println("owner : " + house.getOwner().getName());
        System.out.println("address : " + house.getAddress());
    }
}

 

위처럼 짜면 끝일까? 정말 정상적으로 잘 작동할까 ?

예외를 처리하자. ( 주인이 없는 집이 있을 수가 있으니 )

public class Main {

    public static void main(String[] args) {
        
        House house = houseService.getRandomHouse();
        
        if (house.getOwner() != null)
            System.out.println("owner : " + house.getOwner().getName());
            
        System.out.println("address : " + house.getAddress());
    }
}

 

위에서 한 가지 경우에 대해서 예외를 처리해줬다.

근데 정말 예외가 하나밖에 없을까 ?

몇 가지 상황을 나열해보자.

  • 집과 집 주소는 있지만, 그 집의 주인은 없다.
  • 집과 집 주소도 있고, 그 집의 주인도 있지만, 주인의 이름은 모른다.
  • 집과 집 주인은 있는데, 집 주소는 모른다.

 

간단하게 3개만 나열해봤는데, 물론 위의 상황 말고도 더 있겠지 ?

정말 간단한 예제로도 여러가지의 예외 상황이 있는데, 이런 모든 상황에 대해 if문으로 예외 처리를 한다면 코드 가독성이 떨어지게된다.

그래서 Optional<T> 클래스가 탄생했다.

public class Main {

    public static void main(String[] args) {
        
        House house = houseService.getRandomHouse();
        
        String ownerName = Optional.of(house).map(House::getOwner).map(Person::getName).orElse("Nothing");
      
        System.out.println(ownerName);
    }
}

 

 

 

반환 값이 Optional<T>인 메서드


Optional<T>은 객체를 받아와서 해당 객체가 null인지의 여부를 체크할 수 있게한다.

당연히 Optional<T>를 메서드의 반환값으로 사용할 수도 있다.

public class MyService {

    public static Optional<House> getHouse(Person owner, String address) {
        return Optional.of(new House(owner, address));
    }

    public static Optional<House> getHouse(String name, int age, String address) {
        return getHouse(new Person(name, age), address);
    }

    public static Optional<House> getHouse() {
        return getHouse(new Person(), "");
    }
}

 

위의 MyService를 사용하는 main 클래스는 다음과 같다.

Optional.of() 메서드는 파라미터로 들어온 객체가 null일 경우 NullPointerException을 던진다.

public class Main {

    public static void main(String[] args) {

        House house = null;
//        house = new House(new Person(), "bukgu, 120");

        try {
            String ownerName = Optional.of(house).map(House::getPerson).map(Person::getName).orElse("Nothing");
            System.out.println(ownerName);

            Optional<House> myHouse = MyService.getHouse("홍길동", 15, "Seoul");
            ownerName = myHouse.map(House::getPerson).map(Person::getName).orElse("Nothing");
            System.out.println(ownerName);
        } catch (NullPointerException e) {
            System.out.println("NPE");
        }
    }
}

 

'Programming > Java' 카테고리의 다른 글

[Java] synchronized 키워드  (0) 2020.04.13
[Java] @ 어노테이션  (0) 2020.03.31
[Java ] 함수형 인터페이스 ( Functional Interface )  (0) 2020.03.24
[Java] 메서드 참조 ( Method Reference )  (0) 2020.03.24
[Java] .jar와 .war  (0) 2020.03.20