成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

瞧瞧別人家的判空,那叫一個優雅!

開發 前端
我們在日常開發中的entity對象,一般會使用Lombok框架中的注解,來實現getter/setter方法。

一、傳統判空的血淚史

某互聯網金融平臺因費用計算層級的空指針異常,導致凌晨產生9800筆錯誤交易。

DEBUG日志顯示問題出現在如下代碼段:

// 錯誤示例
BigDecimal amount = user.getWallet().getBalance().add(new BigDecimal("100"));

此類鏈式調用若中間環節出現null值,必定導致NPE。

初級階段開發者通常寫出多層嵌套式判斷:

if(user != null){
    Wallet wallet = user.getWallet();
    if(wallet != null){
        BigDecimal balance = wallet.getBalance();
        if(balance != null){
            // 實際業務邏輯
        }
    }
}

這種寫法既不優雅又影響代碼可讀性。

那么,我們該如何優化呢?

二、Java 8+時代的判空革命

Java8之后,新增了Optional類,它是用來專門判空的。

能夠幫你寫出更加優雅的代碼。

1. Optional黃金三板斧

// 重構后的鏈式調用
BigDecimal result = Optional.ofNullable(user)
    .map(User::getWallet)
    .map(Wallet::getBalance)
    .map(balance -> balance.add(new BigDecimal("100")))
    .orElse(BigDecimal.ZERO);

高級用法:條件過濾

Optional.ofNullable(user)
    .filter(u -> u.getVipLevel() > 3)
    .ifPresent(u -> sendCoupon(u)); // VIP用戶發券

2. Optional拋出業務異常

BigDecimal balance = Optional.ofNullable(user)
    .map(User::getWallet)
    .map(Wallet::getBalance)
    .orElseThrow(() -> new BusinessException("用戶錢包數據異常"));

3. 封裝通用工具類

public class NullSafe {
    
    // 安全獲取對象屬性
    public static <T, R> R get(T target, Function<T, R> mapper, R defaultValue) {
        return target != null ? mapper.apply(target) : defaultValue;
    }
    
    // 鏈式安全操作
    public static <T> T execute(T root, Consumer<T> consumer) {
        if (root != null) {
            consumer.accept(root);
        }
        return root;
    }
}

// 使用示例
NullSafe.execute(user, u -> {
    u.getWallet().charge(new BigDecimal("50"));
    logger.info("用戶{}已充值", u.getId());
});

三、現代化框架的判空銀彈

4. Spring實戰技巧

Spring中自帶了一些好用的工具類,比如:CollectionUtils、StringUtils等,可以非常有效的進行判空。

具體代碼如下:

// 集合判空工具
List<Order> orders = getPendingOrders();
if (CollectionUtils.isEmpty(orders)) {
    return Result.error("無待處理訂單");
}

// 字符串檢查
String input = request.getParam("token");
if (StringUtils.hasText(input)) {
    validateToken(input); 
}

5. Lombok保駕護航

我們在日常開發中的entity對象,一般會使用Lombok框架中的注解,來實現getter/setter方法。

其實,這個框架中也提供了@NonNull等判空的注解。

比如:

@Getter
@Setter
public class User {
    @NonNull // 編譯時生成null檢查代碼
    private String name;
    
    private Wallet wallet;
}

// 使用構造時自動判空
User user = new User(@NonNull "張三", wallet);

四、工程級解決方案

6. 空對象模式

public interface Notification {
    void send(String message);
}

// 真實實現
public class EmailNotification implements Notification {
    @Override
    public void send(String message) {
        // 發送郵件邏輯
    }
}

// 空對象實現
public class NullNotification implements Notification {
    @Override
    public void send(String message) {
        // 默認處理
    }
}

// 使用示例
Notification notifier = getNotifier();
notifier.send("系統提醒"); // 無需判空

7. Guava的Optional增強

其實Guava工具包中,給我們提供了Optional增強的功能。

比如:

import com.google.common.base.Optional;

// 創建攜帶缺省值的Optional
Optional<User> userOpt = Optional.fromNullable(user).or(defaultUser);

// 鏈式操作配合Function
Optional<BigDecimal> amount = userOpt.transform(u -> u.getWallet())
                                    .transform(w -> w.getBalance());

Guava工具包中的Optional類已經封裝好了,我們可以直接使用。

五、防御式編程進階

8. Assert斷言式攔截

其實有些Assert斷言類中,已經做好了判空的工作,參數為空則會拋出異常。

這樣我們就可以直接調用這個斷言類。

例如下面的ValidateUtils類中的requireNonNull方法,由于它內容已經判空了,因此,在其他地方調用requireNonNull方法時,如果為空,則會直接拋異常。

我們在業務代碼中,直接調用requireNonNull即可,不用寫額外的判空邏輯。

例如:

public class ValidateUtils {
    public static <T> T requireNonNull(T obj, String message) {
        if (obj == null) {
            throw new ServiceException(message);
        }
        return obj;
    }
}

// 使用姿勢
User currentUser = ValidateUtils.requireNonNull(
    userDao.findById(userId), 
    "用戶不存在-ID:" + userId
);

9. 全局AOP攔截

我們在一些特殊的業務場景種,可以通過自定義注解 + 全局AOP攔截器的方式,來實現實體或者字段的判空。

例如:

@Aspect
@Component
public class NullCheckAspect {
    
    @Around("@annotation(com.xxx.NullCheck)")
    public Object checkNull(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (arg == null) {
                throw new IllegalArgumentException("參數不可為空");
            }
        }
        return joinPoint.proceed();
    }
}

// 注解使用
public void updateUser(@NullCheck User user) {
    // 方法實現
}

六、實戰場景對比分析

場景1:深層次對象取值

// 舊代碼(4層嵌套判斷)
if (order != null) {
    User user = order.getUser();
    if (user != null) {
        Address address = user.getAddress();
        if (address != null) {
            String city = address.getCity();
            // 使用city
        }
    }
}

// 重構后(流暢鏈式)
String city = Optional.ofNullable(order)
    .map(Order::getUser)
    .map(User::getAddress)
    .map(Address::getCity)
    .orElse("未知城市");

場景2:批量數據處理

List<User> users = userService.listUsers();

// 傳統寫法(顯式迭代判斷)
List<String> names = new ArrayList<>();
for (User user : users) {
    if (user != null && user.getName() != null) {
        names.add(user.getName());
    }
}

// Stream優化版
List<String> nameList = users.stream()
    .filter(Objects::nonNull)
    .map(User::getName)
    .filter(Objects::nonNull)
    .collect(Collectors.toList());

七、性能與安全的平衡藝術

上面介紹的這些方案都可以使用,但除了代碼的可讀性之外,我們還需要考慮一下性能因素。

下面列出了上面的幾種在CPU消耗、內存只用和代碼可讀性的對比:

方案

CPU消耗

內存占用

代碼可讀性

適用場景

多層if嵌套



★☆☆☆☆

簡單層級調用

Java Optional



★★★★☆

中等復雜度業務流

空對象模式



★★★★★

高頻調用的基礎服務

AOP全局攔截



★★★☆☆

接口參數非空驗證

黃金法則

  • Web層入口強制參數校驗
  • Service層使用Optional鏈式處理
  • 核心領域模型采用空對象模式

八、擴展技術

除了,上面介紹的常規判空之外,下面再給大家介紹兩種擴展的技術。

Kotlin的空安全設計

雖然Java開發者無法直接使用,但可借鑒其設計哲學:

val city = order?.user?.address?.city ?: "default"

JDK 14新特性預覽

// 模式匹配語法嘗鮮
if (user instanceof User u && u.getName() != null) {
    System.out.println(u.getName().toUpperCase());
}

總之,優雅判空不僅是代碼之美,更是生產安全底線。

本文分享了代碼判空的10種方案,希望能夠幫助你編寫出既優雅又健壯的Java代碼。

責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2024-11-12 08:20:31

2025-05-30 08:20:54

2025-04-08 08:20:33

2024-10-24 08:21:33

2022-12-12 08:14:47

2025-04-22 08:20:51

2024-12-02 00:59:30

Spring

2025-02-28 08:21:00

2025-03-11 08:20:58

2020-11-03 16:00:33

API接口微服務框架編程語言

2015-09-24 09:22:16

nodejs頁面始末

2017-11-12 21:32:52

戴爾

2016-01-08 09:49:19

DockerDocker案例云應用開發

2020-11-17 09:34:31

API接口后端

2017-09-22 13:22:59

大數據南京大學宿舍

2023-12-30 20:04:51

MyBatis框架數據

2021-07-14 06:31:08

京東互聯網加薪

2021-01-20 05:42:27

RabbitMQMQ vhost

2019-06-11 09:35:50

戴爾

2017-06-13 14:15:51

戴爾協同計算汽車神話
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜不卡福利视频 | 狠狠视频 | 久久精品久久久 | 欧美a级成人淫片免费看 | 亚洲国产成人av好男人在线观看 | 最近中文字幕在线视频1 | 午夜精品久久久久久久久久久久久 | 欧洲精品码一区二区三区免费看 | 黑人性hd| 免费一二区 | 天天草视频 | 成人妇女免费播放久久久 | 毛片韩国 | 亚洲日韩中文字幕一区 | 久久高清| 日本精品一区二区三区在线观看视频 | 欧美精品在线一区 | 久久亚洲欧美日韩精品专区 | 国产精品免费一区二区三区四区 | 337p日本欧洲亚洲大胆精蜜臀 | 4h影视 | 亚洲欧美一区二区三区情侣bbw | 日本三级全黄三级三级三级口周 | 亚洲精品乱码久久久久久按摩 | 国产黑丝av | 国产精品美女久久久久aⅴ国产馆 | 精品国产区 | 亚洲精品久久久久久久久久久久久 | 中文字幕在线观看www | h视频在线免费 | 午夜欧美日韩 | 欧洲一区二区视频 | 午夜综合 | 天天拍天天色 | 久久精品99 | 日本久久精 | 91视频国产一区 | 日韩中文一区二区 | 久久99精品国产 | 91精品国产91综合久久蜜臀 | 在线日韩中文字幕 |