忘記檢查空值引用是應用代碼中一類常見的bug來源。消除NullPointerExceptions的方式之一是確保方法總是返回一個非空值。例如如下方法:
public interface CustomerRepository extends CrudRepository
{
/**
* returns the customer for the specified id or
* null if the value is not found
*/
public Customer findCustomerById(String id);
}
用如下有缺陷的代碼來調用CustomerRepository :
Customer customer = customerRepository.findCustomerById(“123”);
customer.getName(); // 得到空指針錯誤
這段代碼的正確寫法應該是:
Customer customer = customerRepository.findCustomerById(“123”);if(customer != null) {
customer.getName(); // 避免空指針錯誤
}
理想狀態下,如果我們沒有檢查某個值能否為空,我們希望編譯器及時發現。java.util.Optional類讓我們可以像這樣寫接口:
public interface CustomerRepository extends CrudRepository
public Optional
這樣一來,這段代碼的有缺陷版本不會被編譯,開發者必須顯式地檢查這個Optional類型對象是否有值,代碼如下:
Optional
if(optional.isPresent()) {
Customer customer = optional.get();
customer.getName();
}
所以Optional的關鍵點在於確保開發者不用查閱Javadoc就能知道某個方法可以返回null,或者可以把一個null值傳給某方法。編譯器和方法簽名有助於開發者明確知道某個值是Optional類型。關於Optional類思想的詳細描述請參考這裡。
Spring 4.1有兩種方式支持Java Optional。Spring的@Autowired註解有一個屬性"required",使用之後我們可以把如下代碼:
@Service
public class MyService {
@Autowired(required=false)
OtherService otherService;
public doSomething() {
if(otherService != null) {
// use other service
}
}}
替換成:
public class MyService {
@Autowired
Optional
public doSomething() {
otherService.ifPresent( s -> {
// use s to do something
});
}}
另一個能用Optional的地方是Spring MVC框架,可以用於表示某個處理方法的參數是可選的。例如:
@RequestMapping(“/accounts/{accountId}”,requestMethod=RequestMethod.POST)
void update(Optional
這段代碼會告訴Spring其accountId是可選參數。
總之,Java 8的Optional類通過減少空指針錯誤相關的缺陷簡化了代碼編寫,同時Spring能很好地支持Java 8的Optional類。
閱讀更多 IT碼將 的文章