본문 바로가기

개발/BACK

[Java] Optional 클래스 사용법 + NullPointerException

728x90


 

객체 지향 언어인 JAVA로 개발을 하고 있는 분들은 모를 수가 없는 오류가 있다

 

NullPointerException

 

코딩도 사람이 하는지라, 서비스 로직을 구현하다보면 널 체크가 빠진 곳이 있기도 하고

객체 내부 빈 값을 참조하는 경우가 생긴다

 

또한, NULL 값 체크를 이리저리 하다 보면, 더러워진 소스코드로 인해 현기증이 난다

 

JAVA 8 에서는 Optional 이라는 클래스를 사용할 수 있다

 

오라클의 Optional 설명 원본 (출처 : https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)

 

해당 클래스의 주요 기능은, 
Null 체크를 하지 않아도 된다는 것이다

 

null 값을 포함할 수 있는 클래스이기 때문에, 해당 클래스에서는 

클래스 내부에 내장된 메소드들을 이용해서 null 값일 떄의 분기만 처리해주면 되는 장점이 있다

 

출처 : https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

위와 같이 많은 종류의 메소드들을 제공하는데,

 

of() 메소드 처럼 기존의 클래스와 동일하게 Null이면 NPE를 출력하도록 할 수 도 있고,

 

ofNullable() 메소드와 같이 빈 값을 반환할 수도 있고,

 

orElse() 메소드 처럼 Null 값을 대신할 값을 설정해서 반환하도록 할 수도 있다

 

 

여기서, 몇 가지의 메소드들로 예시들을 구현해보겠다 

 


 

1

EXAMPLE

 

Null 체크를 진행해야 할 때 Optional을 이용해 소스 코드 작성하기

 

[ Optional을 사용하지 않았을 때 ]

<기존 코드>
UserVO userVO = userDao.findAll();

if(!CommonUtils.isEmpty(userVO)){
	String name = userVO.getName();
    if(name != null){
    	System.out.println(name);
    }else{
    	throw new RuntimeException("error");
    }
}

 

 

[ Optional을 사용할 때 ]

 

<수정 코드>
//데이터 조회
UserVO userVO = userDao.findAll();
// 널이아니면 출력, 널이면 예외처리
Optional<String> userId = Optional.ofNullable(
	userVO.getName()).orElseThrow(() -> {throw new RuntimeException("error")});

 

 

해당 방법과 같이 if 구문을 사용해서 Null처리를 하지 않고, Optional 클래스를 호출하면서 
한 줄로 예외처리까지 하는 변경된 코드다

 


 

 

2

boolean 값으로 데이터가 Null 값인지 여부 체크하기

 

Optional을 사용해서 Null 값 여부를 체크하게 되면, 다음 소스 코드와 같이 

제어문을 통해 제어할 필요가 없어져서 코드를 관리하기에 효율적이다

<기존 코드>

String userId = userVO.getUserId();

if(userId != null) {
	System.out.println(userId);
}else {
	System.out.println("false");
}

 

 

<수정 코드>

String userId = Optional.ofNullable(userVO).map(UserVO :: getUserId).orElse("false");

System.out.println(userId);

 

 


3

다중 VO 구조로 구현했을 때 

 

<기존 코드>
//사용자 정보 조회
UserVO userVO = userDao.findAll();

if(!CommonUtils.isEmpty(userVO)){
	// UserVO 내에 AddressVO 조회
	AddressVO addressVO = userVO.getAddressVO();
    
    if(!CommonUtils.isEmpty(addressVO)){
    	//AddressVO 내에 zipCode 조회
    	String zipCode = addressVO.getZipCode();
        
        if(zipCode != null){
			System.out.println(zipCode);
		}else{
        	System.out.println("false");
        }
    }
}

 

<수정 코드>

String zipCode = Optional.ofNullable(userVO)
				.map(UserVO :: getAddressVO)
                		.map(AddressVO :: getZipCode)
                		.orElse("false");

System.out.println(zipCode);

 

다중 구조는 이런 방식으로 Null 처리가 가능하다

728x90