thymeleaf 에서 사용하는 문법을 보고 찾아보게 됐다.
th:price="${item?.price}"
⇒ item 에 price 가 있으면 price 값이 나오고, 만약 null 이면 NPE 를 던지지 않고, null 을 리턴한다.
위에 문법은 SpEL의 Safe Navigation Operator 를 사용한 것이다.
"Spring Expression Language(“SpEL”)는 객체 그래프를 런타임에서 조회하고 조작하는 강력한 표현 언어이다.
Safe Navigation Operator 는 SpEL 의 사용방법 중 하나이다.
Safe Navigation Operator 는 NullPointerException을 피하기 위해 사용되며, 그 기원은 Groovy 언어에 있다.
일반적으로 객체에 대한 참조가 있는 경우 해당 객체의 메서드나 속성에 액세스하기 전에 null인지 확인해야 할 수 있다.
이를 방지하기 위해 Safe Navigation Operator 는 예외를 던지지 않고 대신에 null을 반환한다.
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
Car hyundai = new Car("Hyundai");
hyundai.setPlaceOfBirth(new PlaceOfBirth("Seoul"));
String city = parser.parseExpression("placeOfBirth?.city").getValue(context, hyundai, String.class);
System.out.println(city); // Seoul
hyundai.setPlaceOfBirth(null);
city = parser.parseExpression("placeOfBirth?.city").getValue(context, hyundai, String.class);
System.out.println(city); // null - NullPointerException 발생하지 않음.
}
private static class Car {
String name;
public PlaceOfBirth placeOfBirth;
public Car(String name) {
this.name = name;
}
public void setPlaceOfBirth(PlaceOfBirth placeOfBirth) {
this.placeOfBirth = placeOfBirth;
}
}
private static class PlaceOfBirth {
public String city;
public PlaceOfBirth(String city) {
this.city = city;
}
}