java stream api를 많이 사용하실텐데요.
예상치 못하게 NullPointerException 발생을 맞이하는 경우가 있어서 정리해보고자 합니다.
예시
SimpleEntry<String, String> keyValue = new SimpleEntry("test", null);
System.out.println(keyValue.getValue());
SimpleEntry는 java.util의 key - value를 담을 수 있는 클래스입니다.
(HashMap에서 사용하는 그것)
위를 실행하면 어떤 결과가 나올까요?
네. 예상하신것 처럼 "null"입니다.
SimpleEntry<String, String> keyValue = new SimpleEntry<>("test", null);
List<SimpleEntry<String, String>> list = Arrays.asList(keyValue);
Object aNull = list.stream()
.map(e -> e.getValue())
.findAny()
.orElse("널이에요");
System.out.println(aNull);
그렇다면 위의 예시의 결과는 뭘까요?
훗..
list는 SimpleEntry 1개로 이루어진 리스트이고
그 list에서 stream api를 이용하는데
거기서 e.getValue()를 호출했고, 그게 null이니
orElse를 타게되므로 "널이에요"가 출력되겠지?
하지만 결과는 그렇지 않습니다.
Exception in thread "main" java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Optional.<init>(Optional.java:96)
at java.util.Optional.of(Optional.java:108)
...
???
Stream.java를 읽어봅시다.
Stream.java의 findAny 선언 부분인데요. 위와같은 설명이 써있습니다.
findFirst도 동일하게 NPE를 발생시킵니다.
그럼 아래와 같은 상황은 어떨까요?
List<SimpleEntry<String, String>> list = Arrays.asList(
new SimpleEntry<>("test2", "notnull"), new SimpleEntry<>("test", null));
Object aNull = list.stream()
.map(e -> e.getValue())
.findAny()
.orElse("널이에요");
System.out.println(aNull);
이 상황에도 NPE가 발생될까요?
아닙니다. null을 취하지 않으면 발생하지 않습니다.
(위를 findFirst()로 변경해도 동일합니다.)
그럼 아래처럼 filter를 추가하면 어떻게 될까요?
List<SimpleEntry<String, String>> list = Arrays.asList(
new SimpleEntry<>("test2", "notnull"), new SimpleEntry<>("test", null));
Object aNull = list.stream()
// 필터추가
.filter(e -> "test".equalsIgnoreCase(e.getKey()))
.map(e -> e.getValue())
.findAny()
.orElse("널이에요");
System.out.println(aNull);
위의 경우 null을 취하는 상황이 되므로 역시 NPE가 발생됩니다.
마치며
이 역시 별거 아닌것 같지만
버그는 항상 사소한것 부터 오는것이므로 조심합시다.
'테크 노트 > 소소한 개발 팁' 카테고리의 다른 글
티스토리 본문 이미지에 border 넣기 (2) | 2019.04.23 |
---|---|
한글 유니코드를 초성, 중성, 종성으로 쪼개자 (0) | 2019.04.09 |
java, optional의 orElse와 orElseGet의 차이 (2) | 2019.03.31 |
android, 앱 출시하려는데 keystore 잃어버렸을 때 (1) | 2019.03.28 |
github, src refspec master does not match any ... (0) | 2019.03.20 |