Java?Optional優(yōu)雅處理空值與鏈?zhǔn)睫D(zhuǎn)換的實(shí)戰(zhàn)指南
簡介
Optional 是 Java 8 引入的一個(gè)容器類,包路徑是:
java.util.Optional
它用來表達(dá)一種很常見的情況:這個(gè)結(jié)果可能有值,也可能沒有值。
比如按 ID 查詢用戶:
User user = userRepository.findById(1L);
如果找到了,返回 User。
如果沒找到,傳統(tǒng)寫法通常返回 null。
Optional 的寫法是:
Optional<User> user = userRepository.findById(1L);
這段代碼的含義更明確:findById 可能查到用戶,也可能查不到用戶。
一句話概括:Optional 用來把“可能為空”這件事寫進(jìn)方法返回值里,讓空值處理變得更清楚。
為什么需要 Optional
先看一段普通判空代碼:
public String getUserCity(User user) {
if (user != null) {
Address address = user.getAddress();
if (address != null) {
String city = address.getCity();
if (city != null) {
return city;
}
}
}
return "未知城市";
}
代碼本身不復(fù)雜,但層級(jí)一多,判空會(huì)越來越長。
如果中間漏掉一次判空:
return user.getAddress().getCity();
只要 user 或 address 是 null,就會(huì)出現(xiàn):
NullPointerException
使用 Optional 后,可以把“取值、轉(zhuǎn)換、兜底”連在一起:
public String getUserCity(User user) {
return Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.orElse("未知城市");
}
這段代碼表達(dá)的是:
- user 有值就取 address
- address 有值就取 city
- city 有值就返回 city
- 中間任何一步為空,就返回“未知城市”
Optional 的基本結(jié)構(gòu)
Optional<T> 里的 T 表示實(shí)際包裝的數(shù)據(jù)類型。
Optional<String> name; Optional<User> user; Optional<Order> order;
Optional 只有兩種狀態(tài):
- 有值:里面包裝了一個(gè)非
null對象 - 空:里面沒有值
創(chuàng)建一個(gè)有值的 Optional:
Optional<String> name = Optional.of("Java");
創(chuàng)建一個(gè)空的 Optional:
Optional<String> name = Optional.empty();
創(chuàng)建 Optional
常用創(chuàng)建方式有 3 個(gè):
Optional.of(value)Optional.ofNullable(value)Optional.empty()
Optional.of
Optional.of 用來包裝一個(gè)確定不為 null 的值。
Optional<String> name = Optional.of("Java");
System.out.println(name);
輸出:
Optional[Java]
如果傳入 null:
Optional<String> name = Optional.of(null);
會(huì)直接拋出:
NullPointerException
所以 of 適合這種場景:值一定不為空,只是需要包裝成 Optional。
Optional.ofNullable
Optional.ofNullable 是最常見的創(chuàng)建方式。
它允許傳入 null。
String value = null; Optional<String> name = Optional.ofNullable(value); System.out.println(name);
輸出:
Optional.empty
如果傳入非空值:
String value = "Java"; Optional<String> name = Optional.ofNullable(value); System.out.println(name);
輸出:
Optional[Java]
日常項(xiàng)目里,包裝一個(gè)來源不確定的對象時(shí),通常使用 ofNullable。
Optional.empty
Optional.empty 用來創(chuàng)建一個(gè)空的 Optional。
Optional<User> user = Optional.empty();
它常用于方法返回空結(jié)果:
public Optional<User> findUserById(Long id) {
if (id == null) {
return Optional.empty();
}
User user = queryUser(id);
return Optional.ofNullable(user);
}
判斷是否有值
Optional 提供了兩個(gè)常見判斷方法:
isPresent()isEmpty()
isPresent() 表示是否有值:
Optional<String> name = Optional.of("Java");
System.out.println(name.isPresent());
輸出:
true
isEmpty() 表示是否為空,它是 Java 11 新增的方法:
Optional<String> name = Optional.empty(); System.out.println(name.isEmpty());
輸出:
true
判斷后再 get 的寫法可以用,但不算 Optional 最有價(jià)值的寫法:
Optional<String> name = Optional.of("Java");
if (name.isPresent()) {
System.out.println(name.get());
}
更常見的寫法是直接使用 ifPresent、map、orElse 等方法。
get 取值
get() 可以直接取出 Optional 里的值。
Optional<String> name = Optional.of("Java");
System.out.println(name.get());
輸出:
Java
但空 Optional 調(diào)用 get() 會(huì)拋異常:
Optional<String> name = Optional.empty(); System.out.println(name.get());
異常:
NoSuchElementException: No value present
所以實(shí)際項(xiàng)目里更常見的是先明確空值處理方式,而不是直接寫:
optional.get()
更合適的方式是:
optional.orElse(...) optional.orElseGet(...) optional.orElseThrow(...) optional.ifPresent(...)
ifPresent:有值才執(zhí)行
ifPresent 適合處理“有值就做一件事,沒值就不處理”的場景。
Optional<String> name = Optional.ofNullable("Java");
name.ifPresent(value -> System.out.println("name = " + value));
輸出:
name = Java
如果是空值:
Optional<String> name = Optional.empty();
name.ifPresent(value -> System.out.println("name = " + value));
不會(huì)輸出任何內(nèi)容。
ifPresentOrElse
ifPresentOrElse 是 Java 9 新增的方法。
它可以同時(shí)處理有值和無值兩種情況。
Optional<String> name = Optional.empty();
name.ifPresentOrElse(
value -> System.out.println("name = " + value),
() -> System.out.println("name 不存在")
);
輸出:
name 不存在
orElse:為空時(shí)返回默認(rèn)值
orElse 用來給空值設(shè)置默認(rèn)值。
String name = Optional.ofNullable(null)
.orElse("默認(rèn)名稱");
System.out.println(name);
輸出:
默認(rèn)名稱
有值時(shí)返回原值:
String name = Optional.ofNullable("Java")
.orElse("默認(rèn)名稱");
System.out.println(name);
輸出:
Java
orElseGet:為空時(shí)再生成默認(rèn)值
orElseGet 接收的是一個(gè) Supplier。
只有 Optional 為空時(shí),才會(huì)執(zhí)行里面的邏輯。
String name = Optional.ofNullable(null)
.orElseGet(() -> "默認(rèn)名稱");
System.out.println(name);
輸出:
默認(rèn)名稱
orElse 和 orElseGet 的區(qū)別
這兩個(gè)方法很像,但執(zhí)行時(shí)機(jī)不一樣。
準(zhǔn)備一個(gè)方法:
private static String createDefaultName() {
System.out.println("生成默認(rèn)名稱");
return "默認(rèn)名稱";
}
使用 orElse:
String name = Optional.of("Java")
.orElse(createDefaultName());
System.out.println(name);
輸出:
生成默認(rèn)名稱
Java
雖然 Optional 里已經(jīng)有 "Java",但 createDefaultName() 還是執(zhí)行了。
再看 orElseGet:
String name = Optional.of("Java")
.orElseGet(() -> createDefaultName());
System.out.println(name);
輸出:
Java
createDefaultName() 沒有執(zhí)行。
簡單理解:
orElse:默認(rèn)值先準(zhǔn)備好,不管最后用不用
orElseGet:真正為空時(shí),才去生成默認(rèn)值
如果默認(rèn)值只是一個(gè)普通字符串,用 orElse 很自然:
String name = optionalName.orElse("匿名用戶");
如果默認(rèn)值需要查詢數(shù)據(jù)庫、調(diào)用接口、創(chuàng)建復(fù)雜對象,用 orElseGet 更合適:
User user = optionalUser.orElseGet(() -> userRepository.createGuestUser());
orElseThrow:為空時(shí)拋異常
有些場景下,空值不是正常結(jié)果,而是業(yè)務(wù)異常。
比如訂單必須存在:
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new IllegalArgumentException("訂單不存在"));
Java 10 開始,orElseThrow() 可以不傳參數(shù)。
String name = Optional.<String>empty()
.orElseThrow();
空值時(shí)會(huì)拋出:
NoSuchElementException
業(yè)務(wù)代碼里通常更推薦帶上明確的異常類型和提示信息:
User user = userRepository.findById(userId)
.orElseThrow(() -> new IllegalStateException("用戶不存在"));
map:轉(zhuǎn)換里面的值
map 用來把 Optional 里的值轉(zhuǎn)換成另一個(gè)值。
Optional<String> name = Optional.of("Java");
Optional<Integer> length = name.map(String::length);
System.out.println(length.orElse(0));
輸出:
4
如果原來的 Optional 是空的,map 不會(huì)執(zhí)行:
Optional<String> name = Optional.empty();
Optional<Integer> length = name.map(value -> {
System.out.println("計(jì)算長度");
return value.length();
});
System.out.println(length.orElse(0));
輸出:
0
不會(huì)輸出 計(jì)算長度。
map 處理對象屬性
map 很適合用來安全獲取對象屬性。
String city = Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.orElse("未知城市");
這段代碼里:
user為空,直接返回默認(rèn)值address為空,直接返回默認(rèn)值city為空,直接返回默認(rèn)值- 三者都有值,返回真實(shí)城市
不用寫多層 if,也不用擔(dān)心中間某一步出現(xiàn)空指針。
flatMap:處理返回 Optional 的方法
如果轉(zhuǎn)換方法本身返回的就是 Optional,應(yīng)該使用 flatMap。
先看一個(gè)類:
class User {
private final Address address;
User(Address address) {
this.address = address;
}
public Optional<Address> getAddress() {
return Optional.ofNullable(address);
}
}
此時(shí) getAddress() 返回的是:
Optional<Address>
如果使用 map:
Optional<Optional<Address>> address = Optional.of(user)
.map(User::getAddress);
結(jié)果會(huì)變成嵌套結(jié)構(gòu):
Optional<Optional<Address>>
使用 flatMap 可以把嵌套壓平:
Optional<Address> address = Optional.of(user)
.flatMap(User::getAddress);
再配合城市字段:
String city = Optional.of(user)
.flatMap(User::getAddress)
.flatMap(Address::getCity)
.orElse("未知城市");
簡單區(qū)分:
- 方法返回普通值,用 map
- 方法返回 Optional,用 flatMap
filter:按條件保留值
filter 用來給 Optional 里的值加條件。
條件滿足,值保留。
條件不滿足,變成空 Optional。
Optional<Integer> age = Optional.of(20); Optional<Integer> adultAge = age.filter(value -> value >= 18); System.out.println(adultAge.isPresent());
輸出:
true
如果條件不滿足:
Optional<Integer> age = Optional.of(16); Optional<Integer> adultAge = age.filter(value -> value >= 18); System.out.println(adultAge.isPresent());
輸出:
false
常見業(yè)務(wù)寫法:
Optional<User> activeUser = Optional.ofNullable(user)
.filter(User::isActive);
表示:
user 不為空,并且是啟用狀態(tài),才繼續(xù)保留。
or:為空時(shí)切換到另一個(gè) Optional
or 是 Java 9 新增的方法。
它適合處理多個(gè)來源的查找邏輯。
Optional<User> user = findByEmail(email)
.or(() -> findByPhone(phone))
.or(() -> findByUsername(username));
含義是:
- 先按郵箱查
- 查不到再按手機(jī)號(hào)查
- 還查不到再按用戶名查
注意,or 返回的還是 Optional。
User result = findByEmail(email)
.or(() -> findByPhone(phone))
.or(() -> findByUsername(username))
.orElseThrow(() -> new IllegalArgumentException("用戶不存在"));
stream:把 Optional 轉(zhuǎn)成 Stream
stream 是 Java 9 新增的方法。
它可以把一個(gè) Optional 轉(zhuǎn)成包含 0 個(gè)或 1 個(gè)元素的 Stream。
Optional<String> name = Optional.of("Java");
long count = name.stream().count();
System.out.println(count);
輸出:
1
空 Optional:
Optional<String> name = Optional.empty(); long count = name.stream().count(); System.out.println(count);
輸出:
0
它常用于集合處理。
比如有一組用戶 ID,需要查詢用戶,但有些 ID 查不到:
List<User> users = userIds.stream()
.map(userRepository::findById)
.flatMap(Optional::stream)
.collect(Collectors.toList());
這里的 findById 返回 Optional<User>。
flatMap(Optional::stream) 會(huì)自動(dòng)丟掉空結(jié)果,只留下查到的用戶。
實(shí)戰(zhàn) Demo:訂單查詢與金額展示
下面這組代碼可以直接復(fù)制運(yùn)行,演示 Optional 在業(yè)務(wù)代碼里的常見用法。
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class OptionalOrderDemo {
public static void main(String[] args) {
OrderService orderService = new OrderService();
System.out.println(orderService.getBuyerName("A001"));
System.out.println(orderService.getBuyerName("A002"));
System.out.println(orderService.getBuyerName("A404"));
System.out.println(orderService.getPaidAmountText("A001"));
System.out.println(orderService.getPaidAmountText("A002"));
System.out.println(orderService.getPaidAmountText("A003"));
orderService.findOrder("A001")
.filter(Order::isPaid)
.ifPresent(order -> System.out.println("已支付訂單: " + order.getOrderNo()));
try {
Order order = orderService.findOrder("A404")
.orElseThrow(() -> new IllegalArgumentException("訂單不存在"));
} catch (IllegalArgumentException e) {
System.out.println("異常信息: " + e.getMessage());
}
}
static class OrderService {
private final List<Order> orders = Arrays.asList(
new Order("A001", new Buyer("張三", new Address("上海")), new BigDecimal("99.00"), "PAID"),
new Order("A002", new Buyer("李四", null), new BigDecimal("35.50"), "PAID"),
new Order("A003", null, new BigDecimal("88.00"), "CANCELLED")
);
public Optional<Order> findOrder(String orderNo) {
return orders.stream()
.filter(order -> order.getOrderNo().equals(orderNo))
.findFirst();
}
public String getBuyerName(String orderNo) {
return findOrder(orderNo)
.map(Order::getBuyer)
.map(Buyer::getName)
.orElse("未知買家");
}
public String getPaidAmountText(String orderNo) {
return findOrder(orderNo)
.filter(Order::isPaid)
.map(Order::getAmount)
.map(amount -> "支付金額: " + amount)
.orElse("未支付或訂單不存在");
}
public String getBuyerCity(String orderNo) {
return findOrder(orderNo)
.map(Order::getBuyer)
.map(Buyer::getAddress)
.map(Address::getCity)
.orElse("未知城市");
}
}
static class Order {
private final String orderNo;
private final Buyer buyer;
private final BigDecimal amount;
private final String status;
Order(String orderNo, Buyer buyer, BigDecimal amount, String status) {
this.orderNo = orderNo;
this.buyer = buyer;
this.amount = amount;
this.status = status;
}
String getOrderNo() {
return orderNo;
}
Buyer getBuyer() {
return buyer;
}
BigDecimal getAmount() {
return amount;
}
boolean isPaid() {
return "PAID".equals(status);
}
}
static class Buyer {
private final String name;
private final Address address;
Buyer(String name, Address address) {
this.name = name;
this.address = address;
}
String getName() {
return name;
}
Address getAddress() {
return address;
}
}
static class Address {
private final String city;
Address(String city) {
this.city = city;
}
String getCity() {
return city;
}
}
}
運(yùn)行結(jié)果:
張三
李四
未知買家
支付金額: 99.00
支付金額: 35.50
未支付或訂單不存在
已支付訂單: A001
異常信息: 訂單不存在
這個(gè) Demo 里包含了幾個(gè)典型場景:
findOrder:用Optional<Order>表達(dá)訂單可能不存在getBuyerName:用map安全獲取買家姓名getPaidAmountText:用filter判斷訂單狀態(tài)orElse:為空或條件不滿足時(shí)給默認(rèn)文案orElseThrow:訂單必須存在時(shí)拋出業(yè)務(wù)異常
實(shí)戰(zhàn) Demo:查詢不到時(shí)再走備用查詢
實(shí)際項(xiàng)目里,經(jīng)常會(huì)出現(xiàn)多個(gè)查詢?nèi)肟凇?/p>
比如先按郵箱查用戶,查不到再按手機(jī)號(hào)查。
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class OptionalFallbackDemo {
public static void main(String[] args) {
UserService userService = new UserService();
User user = userService.findByEmail("none@example.com")
.or(() -> userService.findByPhone("13800000000"))
.orElseThrow(() -> new IllegalArgumentException("用戶不存在"));
System.out.println(user.getName());
}
static class UserService {
private final List<User> users = Arrays.asList(
new User("張三", "zhangsan@example.com", "13800000000"),
new User("李四", "lisi@example.com", "13900000000")
);
public Optional<User> findByEmail(String email) {
return users.stream()
.filter(user -> user.getEmail().equals(email))
.findFirst();
}
public Optional<User> findByPhone(String phone) {
return users.stream()
.filter(user -> user.getPhone().equals(phone))
.findFirst();
}
}
static class User {
private final String name;
private final String email;
private final String phone;
User(String name, String email, String phone) {
this.name = name;
this.email = email;
this.phone = phone;
}
String getName() {
return name;
}
String getEmail() {
return email;
}
String getPhone() {
return phone;
}
}
}
輸出:
張三
這類寫法比手動(dòng)判斷更緊湊:
Optional<User> user = findByEmail(email);
if (user.isEmpty()) {
user = findByPhone(phone);
}
Optional 和 Stream 的配合
Stream 里的很多方法本身就會(huì)返回 Optional。
比如 findFirst:
Optional<String> first = Arrays.asList("Java", "Kotlin", "Go")
.stream()
.filter(name -> name.startsWith("K"))
.findFirst();
System.out.println(first.orElse("沒有匹配結(jié)果"));
輸出:
Kotlin
再比如求最大值:
Optional<Integer> max = Arrays.asList(10, 20, 30)
.stream()
.max(Integer::compareTo);
System.out.println(max.orElse(0));
輸出:
30
為什么這些方法返回 Optional?
因?yàn)榻Y(jié)果可能不存在。
Optional<String> first = List.<String>of()
.stream()
.findFirst();
空集合里沒有第一個(gè)元素,所以返回空 Optional。
OptionalInt、OptionalLong、OptionalDouble
除了 Optional<T>,Java 還提供了 3 個(gè)基本類型版本:
OptionalIntOptionalLongOptionalDouble
它們用來避免基本類型裝箱。
import java.util.OptionalInt;
public class OptionalIntDemo {
public static void main(String[] args) {
OptionalInt maxAge = OptionalInt.of(30);
System.out.println(maxAge.orElse(0));
}
}
輸出:
30
IntStream 的一些操作也會(huì)返回 OptionalInt:
OptionalInt max = Arrays.asList(10, 20, 30)
.stream()
.mapToInt(Integer::intValue)
.max();
System.out.println(max.orElse(0));
輸出:
30
常見使用建議
適合作為方法返回值
Optional 最適合放在方法返回值上。
public Optional<User> findById(Long id) {
User user = queryUser(id);
return Optional.ofNullable(user);
}
調(diào)用方看到返回值類型,就知道這個(gè)方法可能查不到數(shù)據(jù)。
User user = userRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("用戶不存在"));
不適合作為實(shí)體字段
實(shí)體字段通常不建議寫成 Optional。
public class User {
private Optional<String> nickname;
}
更常見的寫法是保持字段為普通類型:
public class User {
private String nickname;
public Optional<String> getNickname() {
return Optional.ofNullable(nickname);
}
}
原因很簡單:字段表示數(shù)據(jù)本身,Optional 更適合表達(dá)方法返回結(jié)果是否存在。
對于數(shù)據(jù)庫實(shí)體、JSON 序列化、ORM 映射,這種寫法也更自然。
不適合作為方法參數(shù)
方法參數(shù)也通常不建議寫成 Optional。
public void updateNickname(Long userId, Optional<String> nickname) {
}
調(diào)用這個(gè)方法時(shí),反而多了一層包裝:
updateNickname(1L, Optional.of("小張"));
updateNickname(1L, Optional.empty());
更常見的寫法是傳普通參數(shù):
public void updateNickname(Long userId, String nickname) {
}
如果參數(shù)有明確的業(yè)務(wù)含義,可以拆成更清楚的方法:
public void updateNickname(Long userId, String nickname) {
}
public void clearNickname(Long userId) {
}
不適合放進(jìn)集合
集合里通常不建議放 Optional。
List<Optional<User>> users;
更常見的是:
List<User> users;
如果沒有數(shù)據(jù),用空集合表示:
List<User> users = Collections.emptyList();
如果集合中某些元素可能不存在,一般在收集前處理掉空值:
List<User> users = userIds.stream()
.map(userRepository::findById)
.flatMap(Optional::stream)
.collect(Collectors.toList());
get 的使用邊界
get() 只有在已經(jīng)確定有值時(shí)才安全。
if (optional.isPresent()) {
User user = optional.get();
}
但大多數(shù)場景可以改成更直接的寫法。
有默認(rèn)值:
User user = optional.orElse(defaultUser);
空值時(shí)報(bào)錯(cuò):
User user = optional.orElseThrow(() -> new IllegalArgumentException("用戶不存在"));
有值時(shí)執(zhí)行邏輯:
optional.ifPresent(user -> sendMessage(user));
轉(zhuǎn)換字段:
String name = optional.map(User::getName).orElse("匿名用戶");
鏈?zhǔn)秸{(diào)用不宜過長
Optional 支持鏈?zhǔn)秸{(diào)用,但業(yè)務(wù)邏輯很復(fù)雜時(shí),拆成普通變量會(huì)更清楚。
比如這類代碼:
String result = Optional.ofNullable(order)
.map(Order::buyer)
.filter(Buyer::isVip)
.map(Buyer::address)
.map(Address::city)
.filter(city -> city.startsWith("上"))
.map(city -> city + " VIP")
.orElse("普通訂單");
如果中間夾雜很多業(yè)務(wù)規(guī)則,拆開后通常更容易維護(hù):
Optional<Order> orderOptional = Optional.ofNullable(order);
Optional<Buyer> vipBuyer = orderOptional
.map(Order::buyer)
.filter(Buyer::isVip);
String result = vipBuyer
.map(Buyer::address)
.map(Address::city)
.filter(city -> city.startsWith("上"))
.map(city -> city + " VIP")
.orElse("普通訂單");
鏈?zhǔn)秸{(diào)用適合表達(dá)清晰的數(shù)據(jù)流。
邏輯復(fù)雜時(shí),適當(dāng)拆開,變量名本身就是說明。
常用方法匯總
| 方法 | 作用 | 常見場景 |
|---|---|---|
Optional.of(value) | 創(chuàng)建有值的 Optional,值不能為 null | 明確值不為空 |
Optional.ofNullable(value) | 創(chuàng)建可能為空的 Optional | 包裝外部返回值 |
Optional.empty() | 創(chuàng)建空 Optional | 返回空結(jié)果 |
isPresent() | 判斷是否有值 | 簡單分支判斷 |
isEmpty() | 判斷是否為空 | Java 11+ |
ifPresent(...) | 有值時(shí)執(zhí)行邏輯 | 打印、通知、補(bǔ)充操作 |
ifPresentOrElse(...) | 有值和無值分別處理 | Java 9+ |
orElse(...) | 為空時(shí)返回默認(rèn)值 | 默認(rèn)字符串、默認(rèn)數(shù)字 |
orElseGet(...) | 為空時(shí)執(zhí)行 Supplier 獲取默認(rèn)值 | 默認(rèn)值創(chuàng)建成本較高 |
orElseThrow(...) | 為空時(shí)拋異常 | 必須存在的數(shù)據(jù) |
map(...) | 轉(zhuǎn)換內(nèi)部值 | 取字段、格式化 |
flatMap(...) | 轉(zhuǎn)換返回 Optional 的值 | 避免 Optional<Optional<T>> |
filter(...) | 條件過濾 | 狀態(tài)判斷、權(quán)限判斷 |
or(...) | 為空時(shí)切換到另一個(gè) Optional | Java 9+,備用查詢 |
stream() | 轉(zhuǎn)成 0 或 1 個(gè)元素的 Stream | Java 9+,集合流水線 |
總結(jié)
Optional 的重點(diǎn)不是把所有 null 都消滅掉,而是把“結(jié)果可能不存在”這件事表達(dá)清楚。
最常見的使用流程是:
Optional.ofNullable(value)
.map(...)
.filter(...)
.orElse(...);
或者:
repository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("數(shù)據(jù)不存在"));
實(shí)際項(xiàng)目里,Optional 最適合放在方法返回值上,用來表示查詢結(jié)果、匹配結(jié)果、計(jì)算結(jié)果可能為空。
只要控制好邊界,不把它塞進(jìn)實(shí)體字段、方法參數(shù)和集合元素里,代碼會(huì)更容易看出空值處理邏輯。
以上就是Java Optional優(yōu)雅處理空值與鏈?zhǔn)睫D(zhuǎn)換的實(shí)戰(zhàn)指南的詳細(xì)內(nèi)容,更多關(guān)于Java Optional處理空值的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MyBatis查詢數(shù)據(jù),賦值給List集合時(shí),數(shù)據(jù)缺少的問題及解決
這篇文章主要介紹了MyBatis查詢數(shù)據(jù),賦值給List集合時(shí),數(shù)據(jù)缺少的問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
java 操作gis geometry類型數(shù)據(jù)方式
這篇文章主要介紹了java 操作gis geometry類型數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
IDEA “Cannot resolve symbol”爆紅問題解決
最近發(fā)現(xiàn)個(gè)問題,IDEA 無法識(shí)別同一個(gè) package 里的其他類,將其顯示為紅色,本文就來介紹一下IDEA “Cannot resolve symbol”爆紅問題解決,感興趣的可以了解一下2023-10-10
Java 和 JavaScript 真正通用的Base64編碼詳解
這篇文章主要介紹了Java 和 JavaScript 真正通用的Base64編碼詳解的相關(guān)資料,附有Java和Javascript 的Base64編碼,需要的朋友可以參考下2016-11-11
SpringBoot整合RocketMQ批量發(fā)送消息的實(shí)現(xiàn)代碼
這篇文章主要介紹了SpringBoot整合RocketMQ批量發(fā)送消息的實(shí)現(xiàn),文中通過代碼示例講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-04-04

