用 Optional.ofNullable 避免java出现空指针异常

java屏蔽了指针,但是空指针是个例外。java8 加入了Optional,可以更优雅的避免空指针异常。举例说明

package com.ioufev.mqtt.entities;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;

/**
 * @Auther: Zg
 * @Date: 2023/1/4 - 01 - 04 - 22:27
 * @Description: com.ioufev.mqtt.entities
 * @version: 1.0
 */
@Data
@Builder
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private Integer id;
    private String name;
    private String sex;
    private Date date;
}

方式1,传统方法,并不能检测出空指针:

    @SneakyThrows
    @Test
    void nullPointerExTest1() {
        Student stuNull = null;
        Student stu = Student.builder()
                .id(1)
                .date(new Timestamp(new Date().getTime()))
                .name("antetokounmpo")
                .sex("male")
                .build();

        //方式一:不能检测出空指针:
        Map<String, Object> map = new HashMap<>();

        Field[] fields = stuNull.getClass().getDeclaredFields();

        for (Field f : Arrays.asList(fields)
             ) {
            f.setAccessible(true);

            map.put(f.getName(),f.get(stuNull));
        }

        for (Map.Entry<String,Object> entry : map.entrySet()
        ) {
            log.info(entry.getKey() +"---->"+entry.getValue());
        }
    }

在这里插入图片描述

方式2:虽然也出现了空指针,但是直接跳转到了 new Field[]{} 避免了空指针

    @SneakyThrows
    @Test
    void nullPointerExTest2(){
        Student stuNull = null;
        Student stu = Student.builder()
                .id(1)
                .date(new Timestamp(new Date().getTime()))
                .name("antetokounmpo")
                .sex("male")
                .build();

        //方式二:能检测出空指针:
        Map<String, Object> map = new HashMap<>();

        Field[] fields = Optional.ofNullable(stuNull)
                .map(x -> x.getClass())
                .map(y -> y.getDeclaredFields())
                .orElse(new Field[]{});


        for (Field f : Arrays.asList(fields)
        ) {
            f.setAccessible(true);

            map.put(f.getName(),f.get(stuNull));
        }

        for (Map.Entry<String,Object> entry : map.entrySet()
        ) {
            log.info(entry.getKey() +"---->"+entry.getValue());
        }
    }

在这里插入图片描述

正确的写法:

    @Test
    void nullPointerExTest3(){
        Student stuNull = null;
        Student student = new Student();
        Student stu = Student.builder()
                .id(1)
                .date(new Timestamp(new Date().getTime()))
                .name("antetokounmpo")
                .sex("male")
                .build();

        //方式二:能检测出空指针:
        Map<String, Object> map = new HashMap<>();

        Field[] fields = Optional.ofNullable(student)
                .map(Student::getClass)
                .map(Class::getDeclaredFields)
                .orElse(new Field[]{});


        Arrays.asList(fields).forEach(field -> {
            field.setAccessible(true);
            try {
                map.put(field.getName(),field.get(stu));
            }

            catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        });

        map.entrySet().forEach(entry->{
            log.info(entry.getKey()+"---->"+ entry.getValue());
        });
    }

在这里插入图片描述

C# 中 有更优雅的写法:

            EmployeeInfo employeeInfo = new EmployeeInfo();

            string s = (employeeInfo?.EmpPYNo); 
            //判断employeeInfo 是否为null。 如果为null则不执行后面的方法,属性,直接返回null


            string ss = employeeInfo.Phone ?? employeeInfo.EmpName; 
            //如果employeeInfo.Phone 存在则返回左边,否则右边
Java 8 引入了 Optional 类,主要用于解决空指针异常问题,而 `Optional.ofNullable` 和 `Optional.of` 是创建 `Optional` 对象的两种不同方法,它们的区别、用法和示例如下: ### 区别 - `Optional.of` 方法创建 `Optional` 对象时,传入的 `value` 不能为 `null`,否则会抛出空指针异常;而 `Optional.ofNullable` 方法可以传入空值,当传入 `null` 时会创建一个 `value` 为 `null` 的 `Optional` 对象 [^3]。 ### 用法 - **`Optional.of`**:适用于确定传入的值不为 `null` 的情况。若不确定值是否为 `null` 而使用该方法,可能会导致空指针异常。 - **`Optional.ofNullable`**:适用于不确定传入的值是否为 `null` 的情况,它会安全处理 `null` 值,避免空指针异常。 ### 示例 ```java import java.util.Optional; public class OptionalExample { public static void main(String[] args) { // 使用 Optional.of,参数不能为 null try { // 参数为非 null Optional<Integer> optional1 = Optional.of(1); System.out.println("optional1: " + optional1.get()); // 下面这行代码会抛出 NullPointerException // Optional<Integer> optionalNull = Optional.of(null); } catch (NullPointerException e) { System.out.println("Caught NullPointerException: " + e.getMessage()); } // 使用 Optional.ofNullable,参数可以为 null // 参数为 null Optional<Integer> optional2 = Optional.ofNullable(null); System.out.println("optional2 是否存在值: " + optional2.isPresent()); // 参数为非 null Optional<Integer> optional3 = Optional.ofNullable(2); System.out.println("optional3: " + optional3.get()); } } ``` 在上述示例中,`Optional.of(1)` 正常创建了包含值 `1` 的 `Optional` 对象;若尝试使用 `Optional.of(null)` 则会抛出空指针异常。而 `Optional.ofNullable(null)` 安全地创建了一个不包含值的 `Optional` 对象,`Optional.ofNullable(2)` 则创建了包含值 `2` 的 `Optional` 对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值