1. NullPointerException
NullPointerException은 실제 값이 아닌 null을 가지고 있는 객체/변수를 호출할 때 발생하는 예외이다.
String str = null;
System.out.println(str.toString());
|
*이럴 때 예외가 발생하는게 null에는 toString이 없기 때문이다. 문제는 프로그래밍을 하다보면 해당 변수에 null이 들어있는지, 아닌지를 구분하기가 어렵다는 점이다. 그래서 NullPointerException 처리 방법으로 크게 세 가지가 있다.
*일반적으로 NPE(NullPointerException)로 표시한다.
2. 처리방법
2.1. Try-Catch
String s = null;
try {
s = s.toUpperCase(); //s를 대문자로 바꾸면서 NullPointerException 발생
System.out.println(s); //실행되지 않는다.
} catch(NullPointerException e){
s = "empty";
System.out.println(s.toUpperCase()); //catch문에서 대문자로 바꾸어준다.
}finally{
System.out.println("무조건 실행됩니다.");
}
|
*이렇게 한다면 변수를 사용할 때마다 try-catch를 섞으면 코드의 양이 너무 많아질 수 있다.
2.2. if (variable != null)
public String getCityOfMemberFromOrder(Order order) {
if (order != null) {
Member member = order.getMember();
if (member != null) {
Address address = member.getAddress();
if (address != null) {
String city = address.getCity();
if (city != null) {
return city;
}
}
}
}
return "Seoul"; // default
}
|
*객체 안의 객체가 있는 구조에서는 좋지 않은 상황에 직면 할 수 있다.
2.3. Optional
java.util.Optional은 JDK1.8부터 추가되었다.
Optional<T\>은 지네릭 클래스로 'T타입의 객체'를 감싸는 래퍼 클래스이다.
그래서 Optional타입의 객체는 모든 타입의 참조변수를 담을 수 있다.
public final class Optional<T> {
private final T value; // T타입의 참조변수
...
}
|
최종 연산의 결과를 그냥 반환하는게 아니라 Optional 객체에 담아서 반환하는 것이다. 이처럼 객체에 담아서 반환을 하면, 반환된 결과가 null인지 매번 if문으로 체크하는 대신 Optional에 정의된 메서드를 통해서 간단히 처리할 수 있다.
이제 널 체크를 위한 if문 없이도 NullPointerException이 발생하지 않는 코드 작성이 가능하다.
Optional에서 얻는 장점
- NPE를 유발할 수 있는 null을 직접 다루지 않아도 된다
- 수고롭게 null 체크를 직접 하지 않아도 된다
- 명시적으로 해당 변수가 null일 수도 있다는 가능성을 표현할 수 있다. (따라서 불필요한 방어 로직을 줄일 수 있다.)
Optional 기본 사용법
Optional 의 static method 인 empty(), of(), ofNullable() 을 통해서만 Optional 객체를 생성할 수 있다.
참조변수의 값이 null일 가능성이 있으면, of() 대신 ofNullable()을 사용해야한다. of()는 매개변수의 값이 null이면 NullPointerException이 발생하기 때문이다.
Optional<String> optVal = Optional.of(null); //NPE 발생
Optional<String> optVal = Optional.ofNullable(null); // OK
|
Optional<T>타입의 참조변수를 기본값으로 초기화할 때는 empty()를 사용한다. null로 초기화하는 것도 가능하지만, empty()로 초기화하는 것이 바람직하다.
Optional<String> optVal = null ;
Optional<String> optVal = Optional.<String>empty(); // 빈 객체로 초기화
|
Optional 객체의 값 가져오기
Optional<String> optVal = Optional.of("abc");
String str1 = optVal.get(); //optVal에 저장된 값을 반환. null이면 예외 발생
String str2 = optVal.orElse(""); //optVal에 저장된 값이 null일 때는 ""를 반환
|
만약 Optional 없이 쓰면 코드를 아래와 같이 쓸 것이다.
SoundCard soundcard = ...;
if(soundcard != null){
System.out.println(soundcard);
}
|
Optional을 쓰면 아래와 같이 수정할 수 있다.
Optional<Soundcard> soundcard = ...;
soundcard.ifPresent(System.out::println);
|
하지만 그렇다면 null check를 할 때
if(soundcard.isPresent()){
System.out.println(soundcard.get());
}
|
이렇게되는데 기존의 if와 크게 차이가 나지 않아 보인다.
Optional<Soundcard> maybeSoundcard = Optional.ofNullable(someSoundcard);
Soundcard soundcard = maybeSoundcard.orElse(new Soundcard("default"));
|
'👨🏫Study > JAVA' 카테고리의 다른 글
[JAVA] 예외(EXCEPTION) 처리 (0) | 2022.03.31 |
---|---|
[JAVA] 18 - 3. 채팅 서버, 클라이언트 구현 (0) | 2022.03.30 |
[JAVA] 18 - 2. 네트워킹 (0) | 2022.03.29 |
[JAVA] 18 - 1. IO 기반 입출력 및 네트워킹 (0) | 2022.03.25 |
[JAVA] JavaFX (0) | 2022.03.25 |
댓글